在阅读 SICP 时出现了这个问题。为什么(list 'quote '(a b c))
由解释器( Dr.Racket 中的 R5RS )评估为'(a b c)
。对我来说应该是(quote (a b c))
。例如,(list 'quot '(a b c))
被评估为(quot (a b c))
。 'quote
中有什么特别之处?
答案 0 :(得分:6)
根据您正在使用的Lisp(Scheme,Racket,Common Lisp等),您将获得不同的行为,但一般情况下,系统会接受'x
作为简写(quote x)
的em>或句法糖。这两种形式完全等效,它们的值相同:未评估的x
。当结果从系统中出来时,它可能选择以第一种方式打印,以使结果对用户更直观。类似的事情也发生在cons
上。例如,
(cons 1 2)
;=> (1 . 2)
因为这是打印cons单元格(对)的一般方式。但是,有一个特殊的情况定义,当该对的第二部分是另一个列表(空列表()
或另一对),这就是为什么我们有以下。我还写了更多关于如何列表和缺点单元格打印在Recursive range in Lisp adds a period?的答案中。
(cons 1 '())
;=> (1)
(cons 1 '(2 3))
;=> (1 2 3)
现在,我已经编写了上面表达式的值。例如,(cons 1 '(2 3))
形式的值是列表(1 2 3)
。作为一个额外的复杂功能,一些系统(我正在考虑某些语言,特别是Dr. Racket)不会在交互式提示中打印表单的值,而是打印一个表单将产生相同的(对于“相同”)值的某些解释。例如,您可以评估'(1 . 2)
并查看输出(cons 1 2)
,因为这是另一个会产生相同值的表单。如果您正在进行具有referential transparency的纯函数式编程,这会很有帮助,但是如果您不期望它,则会导致一些混淆。
一种很好的方式可以看到我们得到的结果是,无论系统如何打印,我们应该检查它们。我们希望(list 'quote '(a b c))
返回一个列表,其car
是符号quote
,其cadr
是列表(a b c)
。这就是我们得到的(在Dr.Retet 5.3中,语言R 5 RS):
> (display (list 'quote '(a b c)))
'(a b c)
> (display (car (list 'quote '(a b c))))
quote
> (display (cadr (list 'quote '(a b c))))
(a b c)
如果我们使用'qmmmt
代替'quote
:
> (display (list 'qmmmt '(a b c)))
(qmmmt (a b c))
> (display (car (list 'qmmmt '(a b c))))
qmmmt
> (display (cadr (list 'qmmmt '(a b c))))
(a b c)
唯一的区别是,在第一种情况下,display
使用可用于此类列表的速记显示car
是符号quote
的列表。也就是说,它不是显示(quote (a b c))
,而是显示'(a b c)
。
答案 1 :(得分:4)
'(a b c)
和(quote (a b c))
实际上是相同的不同符号。所以如果你的Lisp打印出较短的版本,请不要感到惊讶。
一般来说,'<something>
与(quote <something>)
相同。
QUOTE
来标记应该自己评估的表达式。通常,列表是函数或宏调用,符号是变量。如果您想将这些视为数据,则需要引用它们。
由于在Lisp中经常使用(quote <something>)
,因此引入了缩写版本'<something>
以节省一些打字或阅读...
答案 2 :(得分:2)
display
会发出一些行为。例如。 '(a . (b . (c . ())))
显示(a b c)
。 'quote
显示quote
,'(quote x y)
显示(quote x y)
,而'(quote x)
显示为'x
或(quote x)
。哪一个是依赖于实现的,但两者的意思相同。
作为数据(即引用,如(quote quote)
和它的abbrivation 'quote
)评估结果,符号quote
对于任何LISP都没有什么特别之处,就像{{{ 1}}和'+
碰巧是符号'potato
和+
。任何在没有引用时表示某事的符号在引用时都没有特殊。
答案 3 :(得分:1)
我花了一些时间来理解这个问题。但这只是你的好心的lisp翻译显示(引用(a b c))它的等价形式'(a b c)。由于(quott(a b c))没有这样的等价/句法糖,所以它显示为。