Clojure字符串到符号计算结果错误 [英] Clojure string to symbol evaluates to wrong result
问题描述
user=> ((symbol "or") true false)
false
user=> (or true false)
true
为什么第一个表单求值 false
?我想象两个输入表单是等效的。
Why does the first form evaluate to false
? I'd imagine the two input forms being equivalent.
奇怪的是,颠倒参数的顺序工作原理:
Strangely, reversing the order of the arguments works:
user=> ((symbol "or") false true)
true
user => (or false true)
true
推荐答案
你评估列表(或真假)
,Clojure首先评估第一个项目。在这种情况下,第一个项目是一个命名宏的符号,因此Clojure扩展了宏并评估了结果数据结构(在这种情况下,它将是一个 let
形式) 。
When you evaluate the list (or true false)
, Clojure first evaluates the first item. In this case, the first item is a symbol that names a macro, so Clojure expands the macro and evaluates the resulting data structure (which would be a let
form in this case).
另一方面,当你评估列表((符号或)true false)
Clojure首先评估第一个项目,但在这种情况下,第一个项目是另一个列表! 列表的第一个元素是符号符号
,它命名一个函数,因此Clojure使用参数 或
,再次生成符号或
。换句话说,你基本上评估('或true false)
。
On the other hand, when you evaluate the list ((symbol "or") true false)
, Clojure again first evaluates the first item, but in this case, the first item is another list! The first element of that list is the symbol symbol
, which names a function, so Clojure calls that function with the parameter "or"
, again producing the symbol or
. In other words, you are basically evaluating ('or true false)
.
这里是catch:Clojure采取那个事情,它只是评价,然后去再评价它。相反,由于它不是一个符号的首位,Clojure评估它,然后假设它必须是一个函数。是一个函数?确实,答案是肯定的!
Here's the catch: Clojure does not take that thing that it just evaluated and then go and evaluate it again. Rather, since it wasn't a symbol in the first place, Clojure evaluates it and then assumes that it must be a function. Is it a function? Indeed, the answer is yes!
user> (ifn? 'do)
;=> true
这里是一个有点棘手的地方。在 Symbol
类上的 invoke
的实现与 invoke
在
关键字
类:它假设第一个参数是一个地图,并试图看看自己在那个地图。如果你提供第二个参数,它将使用它作为默认值。
Here's where it gets a little tricky. The implementation of invoke
on the Symbol
class is the same as the implementation of invoke
on the Keyword
class: it assumes that the first argument is a map and tries to look itself up in that map. If you provide a second argument, it will use that as a default value.
现在,显然,如果你尝试处理 true
作为映射,并在该映射中查找符号或
,您将找不到任何内容。所以Clojure有助于返回你提供的默认值: false
。您可以在第二个参数点中设置任何值,只要您的符号在第一个参数中不作为键存在,您将始终返回默认值。
Now, obviously, if you try to treat true
as a map and look up the symbol or
in that map, you'll find nothing. So Clojure helpfully returns the default value that you provided: false
. You could put any value you'd like in that second parameter spot, and as long as your symbol doesn't exist as a key in the first argument, you'll always get back your default value.
这篇关于Clojure字符串到符号计算结果错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!