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

欢迎!请查看关于页面以了解更多关于如何工作的信息。

0
Clojure

Vars 虽然是一种通用的引用结构,但用于实现绑定,并具有反映这一现实的特殊读取器和打印机符号。与 Vars 共享 “namespace/name” 符号的 Keywords 和 Symbols 不同,Vars 在打印时虽然表现为命名,但并不实现 clojure.lang.Named 接口。

所附补丁实现了在 Vars 上实现命名。

示例

`
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 项目这样的应用程序很有用,其中 Vars 常常直接作为值使用,在这些上下文中它们可以与它们表示的值的 Symbols 互换。

7 个答案

0

由 bronsa 发表的评论

使用此补丁在未命名的 Var 上调用 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)

我同样不认为未绑定的 Var 的 “name” 或 “namespace” 有意义,在这种情况下,NPE 可能是可接受的。

0

由 bronsa 发表的评论

我所说的不是未绑定的变量,而是匿名变量,我假设你写错了。

我同意你的看法,抛出异常可能是一种合理的操作,但是我可以在调用name之前检查它是否为nil,而目前没有方法可以检查变量是否被命名,除非直接尝试访问.name字段,这正是这个工单的目的。

0

由 bronsa 发表的评论

我和Reid已经在IRC上就这个问题进行了讨论,以下是我们讨论的内容
变量可以是未命名的(如with-local-vars返回的变量)或包含命名空间和名称部分(这是interned变量的情况)
目前没有任何方法可以检查变量的" internedness",因此尝试访问变量中.name或.namespace字段来检查nil,是目前唯一的做法

鉴于上述情况,目前的补丁似乎不满意,以下是一些提出的解决方案
将变量设置为命名,对于未命名的变量,命名空间返回nil,名称返回"--unnamed--"
保持变量不实现Naming,添加一个"var-symbol"函数,返回匹配变量ns+name的命名空间符号或名为未命名的nil

就我个人而言,我更愿意选择第二个方案,因为我认为变量应该是未命名的,这样似乎才不矛盾。

0

由 arrdem 发表的评论

增加了处理未指定变量情况的补丁。

0

由 arrdem 发表的评论

将所有补丁压缩成一个单独的差异,并更新了附件。

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