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