我正在学习 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
将对两个参数的函数调用 (+
) 求值。
最后一个表达式会发生以下情况:
- 当您按下回车键时,表达式就会被计算。它包含一个普通函数调用 (
eval
) 和一些参数。 - 参数被评估。第一个参数包含引号,它告诉读者产生引号后面的内容(实际的
(+ 3 4)
列表)。 - 没有更多的参数,实际的函数调用被评估。这意味着使用 list
(+ 3 4)
作为参数调用eval
函数。 eval
函数再次执行相同的步骤,找到普通函数+
和参数,并应用它,获得结果。
关于clojure - 为什么 Clojure 允许 (eval 3) 尽管 3 没有被引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14048041/