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

欢迎!请访问关于页面,了解更多关于这个工作方式的信息。

+1
打印

函数的 print-method 实现将生成有效的 edn 语法吗?在某些情况下,它不会

user> (require '[org.httpkit.server :as http])
user> (def s (http/run-server (fn [req] {:status 200}) {}))
user> (prn s)
#function[clojure.lang.AFunction/1]

符号名称不能以数字开头,因此 clojure.lang.AFunction/1 在回读时会导致解析错误

user> (clojure.edn/read-string (prn-str s))
Execution error at user/eval7394 (REPL:68).
Invalid token: clojure.lang.AFunction/1

这是预期的行为吗?如果是这样,打印并重新读取可能包含 fns 的数据结构可能会失败。

1 个回答

0

被选为最佳答案
 
最佳答案

是的,这是预期的行为。以这种方式难以用这种方式序列化函数,且 edn 没有函数实例的表示。

by
我认为创建不可读的标记字面量的数字可能被认为是一个问题。
by
谢谢,Alex。我对不可读的标记字面量很感兴趣。标记字面量的处理是一个独立的话题;但我认为print-method应该产生语法上有效的edn。
by
通常,print-method不会保证产生语法上有效的edn(有很多方式可以违反这个假设),并且甚至不能保证打印Clojure数据。是否支持edn打印或在1.11版本中更加强大地支持print/read回环是一个值得考虑的工作项目。
by
在1.11版本中看到这一点将是极好的。如果它有助于思考这项工作,这里有一个我在发布原始问题时未注意到的细节。

不可读的标记字面量似乎不是由Clojure本身生成的。cider-nrepl为某些对象类型添加了print-method实现,包括clojure.lang.AFunction。这通常是很有帮助的;但是全局多方法的性质意味着这可能会让你感到困惑(或者至少会让你感到困惑)。当我在这个本的repl中测试时,我看到pr-str产生了不同的结果,我感到很惊讶。一种打印数据结构的方式,它是一致的(不受环境的影响),并且被edn读取器保证可读的,确实是一种有用的功能。
by
哦,对了,我没意识到这是由 cider 添加的打印函数。

整个打印基础设施设计为可由用户修改,因此我认为使其独立于环境并不重要。
by
当然,用户可修改性是关键。但明确的范围有助于最小化的惊讶原则。

例如,edn/read 函数的 opts 参数使用户定义的行为清晰简单,易于推理。相比之下,在使用 print-method 时,我没有修改默认行为,但某种程度上却有了改变——全局范围内。这有很好的理由。但令人惊讶且不易追踪。
...