6

(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)?

4

3 回答 3

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
于 2013-06-02T17:23:47.693 回答
2

Scheme 不会计算内引号,因为内引号在外引号内,而引号内的表达式不会被计算。也就是说,如果你写了(quote foo),那么foo将永远不会被评估——即使foo是另一个调用quote

于 2013-06-02T16:55:18.537 回答
1

当方案评估组合时,它会评估运算符。如果它是特殊形式或宏,它将适用。如果不是,它将在应用之前评估每个操作数。

(car (quote (quote abracadabra)))

可以这样评价*

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

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

(let ((quote list) (abracadabra 'simsalabim))
  (car (quote (quote abracadabra)))) 
==> (simsalabim)
于 2013-06-02T20:22:10.930 回答