Common Lisp EVAL函数引用

时间:2017-03-19 13:28:41

标签: lisp common-lisp eval

我的问题很简单(也许是误导性的)。

在Common Lisp中,当我运行以下命令时,我得到相应的结果:

(eval '''boo) => 'boo

另一方面,如果我运行以下命令,我会得到一些不同的东西。

(eval (eval '''boo)) => boo

我的问题是:如果第一个命令的eval“从变量符号中删除”两个引号并在输出处留下一个标记,那么两个嵌套{{1}的可能性如何?函数总共取三个引号?

这特别令人困惑,因为以下结果会导致错误:

eval

3 个答案:

答案 0 :(得分:7)

'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))

答案 1 :(得分:4)

第一个问题:

Evaluating (eval '''boo)

   Evaluating '''boo
   Result: ''boo

   Calling Function EVAL with ''boo
   Function EVAL returns 'boo

Result: 'boo

第二个问题:

Evaluating (eval (eval '''boo))

    Evaluating (eval '''boo)

       Evaluating '''boo
       Result: ''boo

       Calling EVAL with ''boo
       Function EVAL returns 'boo

    Calling Function EVAL with 'boo
    Function EVAL returns boo

Result: boo

答案 2 :(得分:3)

eval是一个功能。在将eval应用于它之前评估其参数。这就是为什么看起来eval"剃掉"两个引号。一个是通过函数应用程序的隐式评估删除的,另一个是eval应用程序本身。

但是当你唤起(eval (eval '''boo))时,外部eval会应用于从内部'boo返回的值eval。等价物是(eval ''boo)

当您尝试(eval 'boing)时,会在eval应用之前评估参数,因此eval会尝试评估boing并出错。

将此与eval的宏版本进行对比,该版本在应用eval之前未评估其参数...

? (defmacro meval (form) `(eval ',form))           
MEVAL
? (meval 'foo)
FOO
? (meval '''foo)
''FOO