2024年Clojure状态调查!中分享您的想法。

欢迎!请查看关于页面获取更多关于如何使用本站的信息。

0
Clojure

变量,虽然是一种通用的引用结构,但用于实现绑定,并且具有反映这一事实的特殊读取器和打印表示法。与共享变量命名"命名空间/名称"表示法的关键字和符号不同,变量在打印时看似实现了命名功能,但并未实现clojure.lang.Named接口。

附带的补丁实现了变量上的命名功能。

示例

`
user=> (name :clojure.core/conj)
"conj"
user=> (namespace :clojure.core/conj)
"clojure.core"
user=> (name 'clojure.core/conj)
"conj"
user=> (namespace 'clojure.core/conj)
"clojure.core"
user=> (name #'clojure.core/conj)
"conj"
user=> (namespace #'clojure.core/conj)
"clojure.core"
user=> (with-local-vars [x 1] (name x))
"--unnamed--"
user=> (with-local-vars [x 1] (namespace x))
nil
user=> (with-local-vars [x 1] (println x))

<Var: --unnamed-->

`

这适用于像CinC项目这样的应用程序,其中变量通常直接用作值,在这些上下文中,它们理想上是可互换的,与它们表示的绑定值相关联的符号。

7个回答

0

评论者:bronsa

在此修补程序中,对无名的变量调用name会导致NPE,我认为这不是期望的行为。

0

评论者:arrdem

我同意,但是这种行为在Core中似乎是标准的。

Clojure 1.6.0
user=> (name nil)
NullPointerException clojure.core/name (core.clj:1518)
user=> (namespace nil)
NullPointerException clojure.core/namespace (core.clj:1526)

我也没有说服自己认为未绑定变量的"名称"或"命名空间"是有意义的,在这种情况下,NPE可能是可接受的。

0

评论者:bronsa

我说的是匿名变量,而不是未绑定变量,我猜你可能写错了。

我同意你可能的观点,抛出异常可能是一种合理的行为,只是我在调用药名之前可以测试它是否为nil,而目前没有方法可以测试变量是否已命名,除非直接尝试访问.name字段,这正是这个项目要做的事情。

0

评论者:bronsa

我和Reid已经在IRC上讨论了这个问题,以下是我们的讨论内容:
变量可以是未命名的(就如同 由with-local-vars返回的变量)或包含一个命名空间和命名部分(这适用于内部的变量) 目前没有测试变量“内部化”的方法,因此测试变量的.name或.namespace字段是当前唯一的方法,间接地尝试访问.name字段,这正是这个项目要解决的问题。

基于以上,当前的补丁似乎不令人满意,以下是一些解决方案的提议:
使变量成为命名的,使命名空间对于未命名的变量返回nil,并且名称返回"--unnamed--" 保持变量不实现Named,添加一个"var-symbol"函数,返回一个匹配变量ns+名称的命名空间符号或对未命名的变量返回nil

就我个人而言,我更愿意实施第二种解决方案,因为我感觉变量不应该被命名,因为它们可以是未命名的,而这在我看来是一个矛盾。

0

评论者:arrdem

明确处理未命名变量案例的补丁已经添加。

0

评论者:arrdem

将所有补丁合并为一个diff,并更新了附件。

0
参考: https://clojure.atlassian.net/browse/CLJ-1488(由arrdem报告)
...