【发布时间】:2020-10-07 05:50:08
【问题描述】:
为什么会这样表达
('+ 10 20)
评估为20?这对我来说真的很奇怪!我本来希望给出一个错误,因为列表的第一个元素 '+ 我不是可以评估的东西!
【问题讨论】:
标签: clojure
为什么会这样表达
('+ 10 20)
评估为20?这对我来说真的很奇怪!我本来希望给出一个错误,因为列表的第一个元素 '+ 我不是可以评估的东西!
【问题讨论】:
标签: clojure
这几乎是 Clojure 的常见问题解答,无论好坏。所以'+ 是(quote +) 的简写,其计算结果为符号+。符号(和关键字)可以被视为函数并在它们的参数中查找自己,所以('+ 10 20) 本质上是(get 10 '+ 20),这就是get 的not-found arity 所以如果“集合”10 不包括符号'+,那么它将返回第三个参数20。
您可能希望针对 10 的关联查找失败并引发异常,但在 Clojure 中有很多情况下查找将返回 nil(或 not-found 版本),因为它从 nil 中受益-双关语的观点,是导致惯用 Clojure 的部分原因。
某些函数会执行这种参数检查:例如,(contains? 10 '+) 会抛出异常,而(get 10 '+) 和(get '+ 10) 都将返回nil。
可能还值得注意的是,以下引发了异常:
user=> ('+ 10 20 30)
Execution error (ArityException) at user/eval39476 (REPL:1).
Wrong number of args (3) passed to: clojure.lang.Symbol
您问“在 clojure 中引用第一个参数的列表的值是否是最后一个参数”,答案是否定的,这是非常具体的双参数函数调用,因为上述逻辑:你不能“调用”一个带有 3 个参数的符号,只有 1 个或 2 个。
值得注意的是这里对于 0 args 情况的区别:
user=> ('+)
Execution error (ArityException) at user/eval39478 (REPL:1).
Wrong number of args (0) passed to: clojure.lang.Symbol
user=> (+)
0
第一种情况是符号查找——至少需要一个集合来查找自身——而第二种情况是零参数的函数调用(clojure.core/+),它返回@的标识值987654343@ 与(*) 返回1 的方式相同。
【讨论】: