请在 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 对象。", :tag 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(...)}}在LispReader的符号元数据中找到{{:dynamic}}条目,并在创建新的{{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中注意到了几行这样的代码。根据这种符号的数量,也许可以使用这种方法向core中的符号添加:dynamic元数据,同时添加一个单元测试来验证在core中的所有符号在.isDynamic返回true时具有:dynamic,反之亦然?

0

评论者:jafingerhut

唉。在我之前的评论中,通过“类似这样的几行代码”,我打算粘贴以下示例

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

0
参考:[https://clojure.atlassian.net/browse/CLJ-859](https://clojure.atlassian.net/browse/CLJ-859)(由alex+import报告)
...