方案何时评估报价?

时间:2013-06-02 16:52:20

标签: lisp scheme sicp

(car ''abracadabra)相当于(car (quote (quote abracadabra)),评估为(car (quote abracadabra)) - > quote

另一方面(car (quote (a b)))评估为a,这对我来说很直观。

所以我的问题是,为什么Scheme不评估(car (quote (quote abracadabra))中的第二个引用(即评估(car (quote abracadabra))(car abracadabra)),但确实评估了(car (quote (a b)))中的引用(即为什么不是答案quote)?

3 个答案:

答案 0 :(得分:9)

在这个表达式中:

(car (quote (quote abracadabra)))
=> 'quote

内部quote未得到评估,它只是符号,没有特别含义。您也可以将其更改为其他任何内容,但结果相同:

(car (quote (foobar abracadabra)))
=> 'foobar

在引用的表达式中,不会评估其他表达式。我们可以使用quasiquoting来强制进行评估,现在这将尝试评估内部引用,从而导致每种情况出现不同的错误:

(car (quasiquote (unquote (quote abracadabra))))  ; (car `,(quote abracadabra))
=> car: contract violation expected: pair? given: 'abracadabra

(car (quasiquote (unquote (foobar abracadabra)))) ; (car `,(foobar abracadabra))
=> foobar: unbound identifier in module in: foobar

答案 1 :(得分:2)

Scheme不评估内部引用,因为内部引用位于外引号内,并且不评估引号内的表达式。也就是说,如果您撰写(quote foo),则永远不会评估foo - 即使foo是对quote的另一次调用。

答案 2 :(得分:1)

当scheme计算组合时,它会评估运算符。然后它将适用,如果它是一个特殊的形式或宏。如果没有,它将在应用之前评估每个操作数。

(car (quote (quote abracadabra)))

可以像这样评估*

  • 汽车评估为#< proc car>。因为它是一个程序以任何顺序评估所有操作数
  • (引用(引用abracadabra))是一个组合,因此
    • 引用评估=> #< macro quote>并且因为它的宏/特殊形式是宏应用
    • apply-macro(#< macro quote>(引用abracadabra)))=> (引用abracadabra)
  • apply-proc(#< proc car>(引用abracadabra))=>报价

*实际上,Scheme可以隐藏任何关键字,因此上下文非常重要。 E.g:

(let ((quote list) (abracadabra 'simsalabim))
  (car (quote (quote abracadabra)))) 
==> (simsalabim)