在Common Lisp中,()
似乎是一种自我评估的形式。 也就是说,它对自身(或其别名nil
)进行评估。 因此,似乎没有必要引用它。 但是在我的quicklisp目录上使用grep会发现许多'()
实例,由许多不同的项目中许多不同的人编写。 写出引用的版本是否有技术原因? Common Lisp the Lanugage,第2版,第1.2.2节,提到了风格上的差异,你可能想用()
强调空列表,用nil
强调布尔假,但没有涵盖这个问题。 斯蒂尔使用的例子之一是:
(append '() '())
。我相信可以写得和:
(append () ())
。那么为什么要把额外的QUOTEs
扔进去呢?当然不会伤害东西。 从风格上讲,一种形式通常优于另一种形式吗? 有人当然可以提出这样的情况,即引用的形式可以更轻松地添加元素,以防您改变主意,并且真的想要一个非空的文字列表。 或者使用引号有一定的对称性,因为非空文本列表也需要它。
这个历史包袱是否与其他被传统继承的/更古老的相关语言相徘徊?
这与 Scheme 不同,在 Scheme 中,您确实需要引用它。 而且看起来你不必在 elisp 中引用它,所以也许以一种迂回的方式它可能与 lisp-1 与 lisp-2 有关?
引用具有非常丰富的属性,清楚地表明您的意思是令牌应该是文字数据。 当您或同事在多年后重新访问代码时更是如此。
您必须使用()
(不带引号)以非计算形式声明空列表,例如参数列表或类超类和槽,其中引号实际上会造成伤害。 实际上,您也可以使用nil
,但为了清楚起见,当声明的内容是列表时,您不应该使用。
以下是规范的相关摘录:
1.4.1.4.4 无
nil
有多种含义。它是COMMON-LISP
包中名为"NIL"
的符号,它是布尔值(和广义布尔值)假,它是空列表,它是空类型(所有类型的子类型)的名称。在Common Lisp中,
nil
可以互换地标记为NIL
或()
。按照惯例,符号的选择提供了一个提示,表明它正在扮演许多角色中的哪一个。For Evaluation? Notation Typically Implied Role ---------- Yes nil use as a boolean. Yes 'nil use as a symbol. Yes '() use as an empty list No nil use as a symbol or boolean. No () use as an empty list.
图 1-1。无的表示法
仅在本文档中,
nil
有时也被标记为 false,以强调其作为布尔值的作用。例如:
(print ()) ;avoided (defun three nil 3) ;avoided '(nil nil) ;list of two symbols '(() ()) ;list of empty lists (defun three () 3) ;Emphasize empty parameter list. (append '() '()) => () ;Emphasize use of empty lists (not nil) => true ;Emphasize use as Boolean false (get 'nil 'color) ;Emphasize use as a symbol
在某些情况下,函数有时被称为"假"或"为真"。由于没有函数对象可以与
nil
相同,并且所有函数对象在被视为布尔值时都表示为真,因此说该函数实际上是假的是没有意义的,说它实际上是真的是无趣的。相反,这些短语只是传统的替代方式,分别表示函数"返回 false"或"返回 true"。
有理由更喜欢写'()
而不是()
,即使()
是自我评估的。它使代码更易于阅读,因为从视觉上看,您处理的是基准面,而不是计算的表单。
这类似于更喜欢写'#(foo bar baz (+ 1 2))
而不是#(foo bar baz (+ 1 2))
的原因。两者都评估了同一件事,但前者在视觉上很明显,foo
、bar
、baz
和(+ 1 2)
都没有被评估。
我从不引用NIL
、()
或T
,当然也不会引用数字或字符串。
如果我在某人的代码中读到'()
,我可能会对作者的意图感到困惑,也许他/她对Common Lisp中引用的理解(这里的初学者问题往往会显示与引号混淆)。
我不能说CL的某些实现在某些时候需要引用()
的可能性,但更有可能的是,作者有其他版本的Lisp的经验,并试图将这种经验应用于Common Lisp,出于习惯或故意。
我认为引用()
的唯一情况是清空了以前非空的常量列表并且有人懒得删除引用。
(defvar *options* '(debug))
。成为
(defvar *options* '())
保留报价甚至可能有意义,以防您计划稍后更改默认值。
在Common Lisp中,()
和nil
都是nil
的表示,它是自我评估的。引用的所有内容都评估其参数,但由于参数是nil
自我评估,因此结果是相同的。编译的代码很可能是相同的。
Scheme 最初是在 CL 的前身下解释的,在最初的报告中,他们或多或少只是用词法闭包和一个命名空间制作了一个 lisp,仅此而已。它看起来更像CL而不是Scheme,但是一个LISP1,所以空列表规则不能是关于Lisp1与Lisp2的,因为Scheme是第一份报告中的Lisp1,不需要引用并且nil
为假值。
对于报告的每个连续版本,Scheme 一直在改进其语法和命名转换。修订做了微妙的变化,他们不怕做出重大改变。他们引入了新的布尔值,更改了名称,将空列表的布尔值从 false 更改为 true,删除了nil
并将t
作为别名更改为#t
和#f
,并被视为无效表达式()
因此需要'()
。
由于如何在CL中做到这一点并不重要,也许一些用两种语言编码的人只是想在他们的生活中有一些对称性。我当然这样做,但我不能代表所有阴谋家。