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

欢迎!有关如何工作的更多信息,请参阅 关于 页面。

0
语法和读取器

函数的读取时间评估按预期工作。例如,将 #=(+ 1 1) 提交到REPL将确实返回 2。然而,像 (if true 1 0) 这样的读取时间评估表单将产生错误。报告的错误在每个宏和特殊表单中并不一致。

#=(if true 1 0)
;;=> Can't resolve if
#=(let [] nil)
;;=> Wrong number of args (2) passed to: clojure.core/let

这是预期行为吗?像Common Lisp这样的语言在这种情况下不会产生错误--例如,代码 #.(if t 1 0) 会返回 1

2 个答案

+2

已选中
 
最佳答案

读取-评估不是公开功能,通常不应使用它。这与Common Lisp有很大(且是故意的)不同。它主要用于一些内部用例,以读取重新构造Java对象的形式,这些对象缺少打印形式。

by
感谢你们和Fogus的快速简洁的回答!我真的很希望我能标记两个回答为最佳回答。:)
by
标记Alex的回答为最佳,因为他说了关键字“你通常不应该使用它” :)
+1
by

Clojure的#=读取形式没有文档说明,因此它的行为由它的工作方式定义。目前,实现是试图将表单中的第一个东西解析为一个Var(对静态方法和构造函数有一些特殊处理)。由于if是一个特殊形式,它的符号解析不到一个Var。然而,即使是解析为宏的符号(如let),也会失败,因为EvalReader将尝试在解析到的Var上调用apply,因为它是宏,所以它不起作用。我认为这应该属于预期行为类别,因为Clojure本身中使用#=非常有限,并且在其能力的范围内。

...