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

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

我同意你的看法,抛出异常可能是一种合理的做法,但我在调用它的name方法之前可以测试nil,而对于一个变量是否命名,目前还没有方法测试,除了直接尝试访问.name字段,这正是此工单的内容。

0

评论者:bronsa

我和Reid在IRC上讨论了这个问题,以下是讨论结果
变量可以是未命名的(如by with-local-vars返回的变量),或者包含一个命名空间和名称部分(这是嵌套变量的情况)
目前没有测试变量“嵌套”的方法,因此访问变量的.name或.namespace字段是测试nil的唯一方法

鉴于上述情况,当前的补丁似乎不尽人意,以下是一些解决方案建议
将变量命名为“命名”,未命名的变量命名空间返回nil,name返回“--unnamed--”
保持变量不实现Named,添加一个“var-符号”函数,返回一个与变量ns+name匹配的命名空间符号,或者对于未命名的变量返回nil

我个人更愿意实施第二种解决方案,因为我认为变量不应该被执行命名,因为它们可以是无名且这在我看来是矛盾的

0

评论者:arrdem

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

0

评论者:arrdem

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

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