user=> ((symbol "or") true false)
false
user=> (or true false)
true
为什么第一个表单评估为false
?我想这两种输入形式是等价的。
奇怪的是,颠倒参数的顺序是有效的:
user=> ((symbol "or") false true)
true
user => (or false true)
true
答案 0 :(得分:4)
评估列表(or true false)
时,Clojure首先评估第一项。在这种情况下,第一个项目是一个命名宏的符号,因此Clojure扩展宏并评估结果数据结构(在这种情况下为let
形式)。
另一方面,当您评估列表((symbol "or") true false)
时,Clojure会再次首先评估第一个项目,但在这种情况下,第一个项目是另一个列表! 列表的第一个元素是符号symbol
,它命名一个函数,因此Clojure使用参数"or"
调用该函数,再次生成符号or
。换句话说,您基本上在评估('or true false)
。
这里有一个问题:Clojure不接受它刚刚评估的东西,然后再去评估它。相反,因为它首先不是符号,所以Clojure会对它进行评估,然后假设它必须是一个函数。这是一个功能吗?的确,答案是肯定的!
user> (ifn? 'do)
;=> true
这里有点棘手。 invoke
类上Symbol
的实现与invoke
类上Keyword
的实现相同:它假设第一个参数是一个地图并试图查看本身在那张地图上。如果您提供第二个参数,它将使用它作为默认值。
现在,很明显,如果您尝试将true
视为地图并在该地图中查找符号or
,您将找不到任何内容。所以Clojure有助于返回您提供的默认值:false
。您可以在第二个参数点中添加任何您想要的值,只要您的符号在第一个参数中不作为键存在,您将始终返回默认值。