Common Lisp EVAL函数引用

Mad*_*ist 0 lisp eval common-lisp

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

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

(eval '''boo) => 'boo
Run Code Online (Sandbox Code Playgroud)

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

(eval (eval '''boo)) => boo
Run Code Online (Sandbox Code Playgroud)

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

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

(eval 'boing) => ERROR. BOING is unbound. 
Run Code Online (Sandbox Code Playgroud)

Syl*_*ter 7

'boo是.的缩写(quote boo).在代码中,quote是一种特殊的形式,它可以评估任何它的参数,仅此而已.因此boo.当这个值传递给它的数据时,不再是代码,而是为了创建foo你需要的符号quote.

'''boo是.的缩写(quote (quote (quote boo))).在评估它时,它完全像以前一样,它变成(quote (quote boo))了一个包含两个元素的列表,其中第二个元素是两个元素的列表.

因为eval它是一个函数,它首先计算参数,然后它评估结果,因为函数应该这样做.因此在第一次评估之后(quote (quote foo))变为第二次离开符号.(quote foo)evalfoo

如果eval获得符号,foo则意味着它应该获得foo全局命名空间中变量绑定的值.从而:

(defparameter *test* 5)
(eval '*test*)
; ==> 5
Run Code Online (Sandbox Code Playgroud)

由于论证是(quote *test*)在评估之后变成的*test*.eval看到符号并获取值5,这就是结果.如果*test*没有约束,你会得到你得到的错误.

(defparameter *test-symbol* '*test)
(eval *test-symbol*)
Run Code Online (Sandbox Code Playgroud)

同样在这里.因为它是一个函数*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
Run Code Online (Sandbox Code Playgroud)

有时我会看到初学者做的事情'('(a) '(b)).这是一个错误,因为在评估时,您最终将列表((quote (a)) (quote (b)))作为数据,而这很少是意图.当使用像list参数这样的函数进行评估时,你需要适当引用:

(list '(a) *result* '(b))
; ==> ((a) (quote foo) (b))
Run Code Online (Sandbox Code Playgroud)


Dou*_*rie 5

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
Run Code Online (Sandbox Code Playgroud)


Rai*_*wig 5

第一个问题:

Evaluating (eval '''boo)

   Evaluating '''boo
   Result: ''boo

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

Result: 'boo
Run Code Online (Sandbox Code Playgroud)

第二个问题:

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
Run Code Online (Sandbox Code Playgroud)