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 中的表达式以确保即使报告对它模棱两可也能正常工作的原因。