我正在学习Clojure并尝试通过与Python的类似功能相似来理解读者,引用,评估和同质性.
在Python中,避免(或推迟)评估的一种方法是将表达式包装在引号之间,例如.'3 + 4'
.您可以稍后使用eval
,例如,eval('3 + 4')
屈服7
.(如果只需要引用Python值,则可以使用repr
函数而不是手动添加引号.)
在Lisp中,您使用quote
或'
用于引用和eval
评估,例如.(eval '(+ 3 4))
屈服7
.
因此在Python中,"引用"的东西由字符串表示,而在Lisp中,它由quote
作为第一项的列表表示.
我的问题,最后:为什么Clojure允许(eval 3)
虽然3
没有引用?这只是Lisp风格的问题(尝试尽可能给出答案而不是错误)或者还有其他原因吗?这种行为对Lisp是否必不可少?
简短的回答是数字(例如符号和字符串)对自己进行评估.引用指示lisp(读者)在报价后面传递未评估的内容.eval
然后在编写它时获取该列表,但没有引用,然后对其进行求值(在这种情况下(eval '(+ 3 4))
,eval
将+
通过两个参数计算函数call()).
最后一个表达式会发生以下情况:
eval
)和一些参数.(+ 3 4)
列表).eval
使用list (+ 3 4)
作为参数调用函数.eval
函数再次执行相同的步骤,找到正常函数+
和参数,并应用它,获得结果.其他答案已经解释了机制,但我认为哲学点在于 lisp 和 python 看待“代码”的不同方式。在 python 中,表示代码的唯一方法是字符串,因此尝试计算非字符串当然会失败。Lisp 具有更丰富的代码数据结构:列表、数字、符号等等。所以表达式(+ 1 2)
是一个列表,包含一个符号和两个数字。评估列表时,必须首先评估其中的每个元素。
因此,在运行 lisp 代码的正常过程中需要计算一个数字是非常自然的。为此,数字被定义为“对自身进行评估”,这意味着它们在评估后与之前相同:只是一个数字。该eval
函数对编译3
器在编译(例如,较大表达式(如(+ 5 3)
. 对于数字来说,这意味着不要管它。