1

我正在阅读这个 Scheme 教程,在第3 节(制作列表)中,那个家伙说you should write '() to represent an empty list。但是对于我编写的每个测试,它似乎与使用 just 具有相同的效果()

另外,据我了解,引号意味着解释器不会评估表达式,但似乎解释器知道'符号后面的内容,因为这样做会(cons 1 '())产生(1),而这样做会(cons 1 'abc)产生(1 . abc),所以它知道'()是一个空列表但是'abc是不是。

4

2 回答 2

5

一些 Scheme 实现允许 bare()作为 的同义词'(),但只有引用的形式是标准的。

至于你的第二个问题:考虑

(define abc '(1 2 3))
(define def '(1 2 3))

(cons 0 'abc)
(cons 0 'def)
(cons 0 abc)
(cons 0 def)

在前两个表达式中,abc并且def不被评估,所以它们保持符号。在后两者中,它们被评估为它们所代表的对象,它们都等于 list (1 2 3)

于 2013-10-19T16:14:31.870 回答
1

TL;DR:为了确保您的应用程序按设计工作,您应该引用空列表,因为它不确定它是否可以正常工作。请参阅下面的长答案。

至于 Scheme 如何处理引用的值,引用 '(+ 3 4 5) 使表达式成为不被评估的常量。这很像创建一个包含代码的字符串,例如“if(a == 0) return 4;” 在 Java 或 C 中。不同之处在于带引号的表达式是结构化数据而不是字节序列。

(cons 1 'abc)并且(cons 1 '())做同样的事情。一个 cons 有两个值的占位符,这两个表达式以完全相同的方式设置两个值。只有display(和repl)知道以结尾的列表()应该以不同的方式显示,而不是(1 . ())像实际存储的那样。

关于需要引用空列表的长答案

这一切都归结为您使用的标准。今天的大多数实现都R5RS需要引用空列表,因为空列表不是表达式。实现可能仍然允许它,因为它不会干扰正确的 Scheme 应用程序。以下是R5RS 报告中的引述:

注意:在 Lisp 的许多方言中,空组合 () 是合法的表达方式。在 Scheme 中,组合必须至少有一个子表达式,因此 () 不是语法上有效的表达式。

这实际上发生在R3RS 中(在过程调用下),所以它已经存在了一段时间。然而,当在 R6RS 中寻找它时,它似乎已经从该部分中消失了,这让我认为他们已经恢复了它,以便它可以自我评估。但是,我在语言更改部分找不到它。

在查看R7RS 草案(NB:PDF)时,来自 R5RS 的部分又回来了,所以我猜这是 R6RS 报告中的错误。这可能是racket(可能还有其他实现者)允许()作为 R6RS 中的表达式以确保即使报告对它模棱两可也能正常工作的原因。

于 2013-10-19T20:12:30.627 回答