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

欢迎!请查看 关于 页面,了解更多关于这里运作方式的信息。

0
Clojure

变量,尽管是一个通用的引用结构,却用于实现绑定,同时具有反映这一事实的特殊读取器和打印机符号。与共享 "命名空间/名称" 符号的 Keywords 和 Symbols 不同,变量在打印时虽然像命名的一样,但并不实现 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)

我也没有说服自己去相信未绑定变量的“名称”或“命名空间”是有意义的,在这种情况下,NullPointerException (NPE) 可能是可接受的。

0

由 bronsa 发布的评论

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

我同意你的看法,抛出异常可能是一种合理的行为,但我可以调用其 name 之前测试它是否为 nil,而测试一个变量是否有名称却没有方法,除非直接尝试访问 .name 字段,这正是这个 bugs 的目的。

0

由 bronsa 发布的评论

我和 Reid 在 IRC 上讨论了这个问题,以下是我们的讨论内容
变量可以是无名的(例如,with-local-vars 返回的变量)或者同时包含命名空间和名称部分(这是 interned 变量的情况)

基于上述讨论,当前的补丁似乎并不令人满意,以下是一些建议的解决方案
使 Var 可命名,对于无名的 Var,使命名空间返回 nil,名称返回"--unnamed--"
保持 Var不休实现 Named,添加一个 "var-symbol" 函数,返回一个与 Var 的 ns+name 匹配的命名空间符号,或对于无名的 Var 返回 nil

我认为,我会更喜欢第二种解决方案的实施,因为我认为 Variable 没有理由被称为 Named,因为它们可以是匿名的,这在我看来像是一种矛盾。

0

由 arrdem 发布的评论

添加了明确处理无名称变量情况的补丁。

0

由 arrdem 发布的评论

将所有补丁压缩到一个单个 diff 中并更新了附件。

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