'boo
是(quote boo)
的缩写。在代码中,quote
是一种特殊的形式,它可以评估它的任何争论,仅此而已。因此boo
。当此值传递给它的数据并不再编码时,但为了创建符号foo
,您需要quote
。
'''boo
是(quote (quote (quote boo)))
的缩写。在评估它时,它完全和以前一样,它变成了(quote (quote boo))
,这是一个包含两个元素的列表,其中第二个元素是两个元素的列表。
由于eval
是一个函数,它首先评估参数,然后评估函数应该做的结果。因此(quote (quote foo))
在第一次评估后变为(quote foo)
并且eval
起飞,第二次离开符号foo
。
如果eval
得到一个符号foo
这意味着它应该得到变量foo
在全局名称空间中的值。因此:
(defparameter *test* 5)
(eval '*test*)
; ==> 5
由于参数是(quote *test*)
,其评估后变得*test*
。eval
看到符号并获取值5
,这是结果。如果*test*
未绑定,则会出现您收到的错误。
(defparameter *test-symbol* '*test)
(eval *test-symbol*)
同样在这里。由于它是一个函数*test-symbol*
评估为符号*test*
,这就是eval
看到的值,它取值5
。
(defparameter *result* (eval '''foo))
*result*
; ==> (quote foo) but often the REPL shows 'foo
(consp *result*)
; ==> t
(length *result*)
; ==> 2
(car *result*)
; ==> quote
(cadr *result*)
; ==> foo
有时候我看到初学者会做一些类似'('(a) '(b))
的事情。这是一个错误,因为在评估时,您最终得到的数据列表为((quote (a)) (quote (b)))
,而且很少有这种意图。当使用功能类似list
的参数被评估,并需要适当地引用:
(list '(a) *result* '(b))
; ==> ((a) (quote foo) (b))