在 clisp 中,有什么区别?
(eval '(+ 1 2))
(eval (+ 1 2))
答案 0 :(得分:7)
第一个会将列表(+ 1 2)
传递给(cons '+ (cons 1 (cons 2 nil))
函数,该列表eval
与'(+ 1 2)
函数相似,然后将评估该表达式,并生成答案,3。表达式eval
是一种引用表达式的方式,因此表达式可以作为数据逐字传递,而不是立即求值。将其传递给(+ 1 2)
函数将对其进行评估。
第二个将评估表达式3
以获得结果eval
,然后将其传递给{{1}}函数。一个数字评估自己,所以它将返回与第一个案例相同的答案,3。
答案 1 :(得分:3)
看来 (eval(+ 1 2))将首先计算(+ 1 2),然后使用(eval 3)
(eval'(+ 1 2))将表达式(+ 1 2)转换为eval,并让eval解释它。
答案 2 :(得分:1)
所有函数(除了原语和一些特殊函数)如eval首先计算所有参数,然后将它们传递给函数体。
但是,可以通过引用来抑制对参数的评估。在这种情况下,S表达式本身作为参数传递,而不是首先进行求值。
(eval(+ 1 2))=>首先(+ 1 2)得到评估=> (eval 3)=>这给出了答案3
(eval'(+ 1 2))=>引号防止参数被评估=> (+ 1 2)作为参数传递=>然而,评估S表达的结果也是3。
以下示例可以更好地理解差异:
(eval(cons(+ 1 2)(+ 3 4)))=>这成为(eval(3 7))=>这给出了“3不是函数”的错误,因为要评估的S表达式是(3 7)
(eval'(cons(+ 1 2)(+ 3 4)))=>这变得像在REPL =>上打字(cons(+ 1 2)(+ 3 4))评估该S-表达得到结果(3.7)