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

欢迎!请参阅 关于 页面以获取更多有关该功能的说明。

0
Clojure 作者
我确信“内置”可能不是这里的正确术语,但我不知道这些是如何命名的。

今天早些时候我在修复 clojail 的一个错误时遇到了这个问题。内置变量,尤其是以下没有源链接的列表中的变量: http://clojure.github.com/clojure/clojure.core-api.html, 尽管是动态的,但没有 :dynamic 元数据。这包括 \*in\*, \*out\*, 和 \*err\* 等。以下是一些示例


user=> (meta #'*err*)
{:ns #<Namespace clojure.core>, :name *err*, :added "1.0", :doc "代表打印操作的默认标准错误 java.io.Writer 对象。\n\n  默认为 System/err,包装在 PrintWriter 中"}
user=> (meta #'*in*)
{:ns #<Namespace clojure.core>, :name *in*, :added "1.0", :doc "代表读取操作的默认标准输入 java.io.Reader 对象。\n\n  默认为 System/in,包装在 LineNumberingPushbackReader 中"}
user=> (meta #'*out*)
{:ns #<Namespace clojure.core>, :name *out*, :added "1.0", :doc "代表打印操作的默认标准输出 java.io.Writer 对象。\n\n  默认为 System/out,包装在 OutputStreamWriter 中", :tag java.io.Writer}
user=> (meta #'*ns*)
{:ns #<Namespace clojure.core>, :name *ns*, :added "1.0", :doc "代表当前命名空间的 clojure.lang.Namespace 对象。"}

5 回答

0
作者

评论者:[email protected]

最近用户列表上的讨论似乎与此相关:(链接:http://groups.google.com/group/clojure/browse_thread/thread/d5efd00c699f73a7 文本:Should intern obey :dynamic?)。

这似乎归结为这样的信息:一个 Var 是否动态(或不是)被复制了一次。一次作为键为 {{:dynamic}} 的元数据,一次是 Clojure 变量的 Var 类的一个布尔字段。这个布尔字段可以通过调用 Var 的 {{isDynamic()}} 方法来获得。

混淆源于 {{:dynamic}} 和 {{.isDynamic}} 可能会相互不同步。在这个情况下,{{.isDynamic}} 是真理的来源。

0
评论由:[email protected] 提出

{{Compiler$Parser.parse(...)}} 在符号的元数据中找到{{:dynamic}}条目,并由{{LispReader}}传递,当创建新的{{DefExpr}}时,这会生成在运行时创建变量时调用{{setDynamic(...)}}的代码。

根据我的了解,一旦发生,{{:dynamic}}条目就不再相关。它似乎仅作为一种通过读者与编译器通信的方式被实现。一且编译器收到消息,它就不再需要了。保留它似乎只会引起困惑。

Clojure核心的Java层创建的动态变量不使用{{:dynamic}}机制,它们直接{{setDynamic()}}。这就是为什么它们在元数据映射中没有{{:dynamic}}的原因。

- 也许编译器应该省略运行时元数据映射中的{{:dynamic}},因为它已经完成了它的目的。
- 也许Clojure应该提供{{dynamic?}}函数。
(defn dynamic? [^clojure.lang.Var v] (.isDynamic v))

或者,也许对于1.4版本,我们应该废除{{:dynamic}},只强制执行已建立的命名约定:(*earmuffs*)是动态的,(其余的一切)不是。(编译器在1.3中警告违反此约定的情况。)
0

评论由:jafingerhut 提出

我最近在core.clj中注意到这样几行代码。根据类似符号的数量,这种方法可能被用来将:dynamic元数据添加到核心的符号中,同时添加一个单元测试来验证核心中的所有符号只有当.isDynamic返回true时才具有:dynamic?

0

评论由:jafingerhut 提出

呃。在我之前的评论中,所说的“这样几行代码”是指以下示例

(alter-meta! #'agent assoc :added "1.0")

0
参考资料:https://clojure.atlassian.net/browse/CLJ-859(由 alex+import 提出)
...