2013-10-01 52 views

回答

5

(list '+ '1 '2)产生符号列表+和数字12。评估将查找由符号+命名的函数和带参数12调用它。

(list + '1 '2)产生由符号+命名的功能以及编号12的功能列表。评估它将调用已经直接作为列表元素的函数,并使用来自列表其余部分的参数。

从未有必要引用的数字,顺便说一句。他们自我评估。

编辑

更有趣的情况下,你没有在你的标题地址是在(eval '('+ 1 2))情况下会发生什么?为什么会出现这种不返回3像其他情况下,所有最终调用由+的论据12命名的函数?

答案是,它是不同的,因为这个时候,你所引述的符号+的两倍。因此,符号不会被解析为它所命名的函数,而是符号本身被称为函数。

现在什么是当一个符号被作为函数调用的行为?它将其第一个参数视为地图,并将其视为该地图中的关键字。但是号码1显然不是地图,所以现在通常会返回nil来指示找不到匹配的密钥。

在这种情况下,虽然,有第二个参数来调用符号+,并且第二个参数被用作默认值时,没有发现匹配键返回。所以这就是为什么表格(eval '('+ 1 2))返回2

编辑2

OK,现在终于回答这个问题:为什么引用列表产生不同的结果不是调用list功能具有相同的参数。这是因为报价'停止它用在列表上的所有评价,但list功能与他们产生一个列表作为元素之前评估其论点。

这些差异在打印各种形式,而不是直接发送到eval的一切都变得很清楚:

user> '(+ 1 2) 
(+ 1 2) 
user> '('+ 1 2) 
((quote +) 1 2) 
user> (list '+ '1 '2) 
(+ 1 2) 
user> (list + '1 '2) 
(#<core$_PLUS_ [email protected]> 1 2) 

你看,第一和第三种情况产生打印同样的结果,因为在这两种这些案例你曾经引用过+。在第二种情况下,+是引用而不是两次,并在最后它不是在所有的报价。

编辑3

最后一个除了应该有希望进一步澄清的事情:除非它的第一个元素名称的宏或特殊的运算符,eval将递归评估列表中的所有元素(包括第一)前通过将其(被评估的)第一个参数作为函数与列表的其余部分作为参数来评估列表本身。

如果第一个元素是'+(quote +)(这些都写一样的东西,所引用的符号+两种不同的方式),将评估的符号+,并且将被称为功能。

如果第一个元素是+,那么将评估为实际加法函数(clojure.core$_PLUS_)。如果它已经是该功能,它将保持不变(除了列表和符号之外,基本上所有类型都是自我评估的)。在这两种情况下,eval都会调用该函数。