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 TEXT:Should intern obey :dynamic?)。

这似乎归结为这样的信息:变量的动态性(或非动态性)信息被重复了。一次是在具有键 {{:dynamic}} 的元数据中,一次是在实现 Clojure 变量的 Var 类上的布尔字段中。这个布尔值可以通过调用 Var 的 {{isDynamic()}} 方法来获得。

混淆的原因是显然 {{:dynamic}} 和 {{.isDynamic}} 似乎无法同步。在这种情况下,{{.isDynamic}} 是真实信息的来源。

0
评论者:[email protected]

{{Compiler$Parser.parse(...)}} 在符号的元数据中找到由 {{LispReader}} 留下的 {{:dynamic}} 条目,并在创建新的 {{DefExpr}} 时传递它,这反过来又生成了在运行时创建 var 时将调用 {{setDynamic(...)}} 的代码。

据我看来,一旦发生这种情况,{{:dynamic}} 条目就无关紧要了。它似乎只是作为一个通过(通过读取器)与编译器通信的方式实现。一旦编译器得到了消息,它就不再需要。保留它似乎只会引起混淆。

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

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

或者,也许人们可以考虑,在 1.4 版本中,完全取消 {{:dynamic}} 并只强制执行既定的命名约定:{{\*earmuffs\*}} 是动态的,{{else-everything}} 不是。(在 1.3 版本中,编译会警告违反此约定的行为。)
0

评论者:jafingerhut

我最近在 core.clj 中注意到几行类似这样的代码。根据这种符号的数量,也许可以使用这种方法将 :dynamic 元数据添加到 core 中的符号,并附带一个单元测试来验证当且仅当 .isDynamic 返回 true 时,core 中的所有符号都有 :dynamic。

0

评论者:jafingerhut

啊。在我上一个评论中,我想表达的是要粘贴以下内容作为示例

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

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