5

在 Common Lisp 中,它似乎()是一种自我评估的形式。也就是说,它对自身(或其别名nil)求值。所以似乎没有必要引用它。但是在我的 quicklisp 目录上使用 grep 会发现'()许多不同的人在许多不同的项目中编写的实例。写出引用的版本是否有技术原因? Common Lisp the Lanugage, 2nd Edition , Section 1.2.2提到了风格上的差异,您可能想用 强调空列表,用 强调()布尔值 false nil,但没有涵盖这个问题。斯蒂尔使用的例子之一是:

(append '() '())

...我相信可以这样写:

(append () ())

...那为什么要把多余QUOTEs的东西扔进去呢?当然它不会伤害事情。从风格上讲,一种形式通常比另一种形式更受欢迎吗?有人肯定会提出这样的情况,即引用的形式可以更简单地添加元素,以防你改变主意,并且真的想要一个非空的文字列表。或者使用引用有一定的对称性,因为非空文字列表也需要它。

这种历史包袱是从其他/更古老的相关语言中流传下来的吗?

这与 Scheme 不同,您确实需要引用它。而且似乎您不必在 elisp 中引用它,所以也许以一种迂回的方式,它可能与 lisp-1 与 lisp-2 有关?

4

4 回答 4

8

引用具有非常丰富的属性,清楚地说明您的意思是令牌应该是文字数据。当您或同事多年后重新访问代码时更是如此。

您必须使用()(不带引号)以非评估形式声明一个空列表,例如参数列表或类超类和插槽,其中引号实际上会造成伤害。实际上,您也可以使用nil,但为了清楚起见,您不应该在声明的事物是列表时使用。


这是规范的相关摘录:

1.4.1.4.4 无

nil有多种含义。它是COMMON-LISP包中名为的符号"NIL",它是布尔值(和广义布尔值)false,它是空列表,它是空类型(所有类型的子类型)的名称。

在 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 的符号

仅在本文档中,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并且所有函数对象在被视为布尔值时都表示为真,因此说该函数实际上是错误的是没有意义的,而说它是字面意思是真的也很无趣。相反,这些短语只是分别表示函数“返回假”或“返回真”的传统替代方式。

于 2016-05-25T10:54:59.363 回答
4

即使是自我评估'(),也有理由更喜欢写作。它使代码更易于阅读,因为在视觉上很明显您正在处理一个数据,而不是一个评估形式。()()

这类似于喜欢写作的'#(foo bar baz (+ 1 2))原因#(foo bar baz (+ 1 2))。两者都对同一事物进行评估,但前者在视觉上很明显,foo, bar,baz(+ 1 2)within 没有被评估。

于 2016-05-25T00:01:42.757 回答
3

我从不引用NIL, ()or T,当然也不会引用数字或字符串。

如果我阅读'()某人的代码,我可能会对作者的意图以及他/她对 Common Lisp 中引用的理解感到困惑(这里的初学者问题往往会与引用混淆)。

我不能说 CL 的某些实现在某些时候需要引用()的可能性,但作者更有可能有其他 Lisp 风格的经验,并试图将这种经验应用于 Common Lisp,出出于习惯或故意。

我认为引用可能有意义的唯一情况()是,以前的非空常量列表被清空并且有人没有费心删除引用。

(defvar *options* '(debug))

...变成

(defvar *options* '())

如果您打算稍后更改默认值,保留报价甚至可能是有意义的。

于 2016-05-25T07:43:19.760 回答
2

在 Common Lisp中(),和nil都是nil自我评估的表示形式。引用的所有内容都对其论点进行评估,但是由于论点nil是自评估的,因此结果是相同的。编译后的代码很可能是相同的。

Scheme 最初是在 CL 的前身下解释的,在第一份报告中,他们或多或少只是做了一个带有词法闭包和一个命名空间的 lisp,仅此而已。它看起来更像 CL 而不是 Scheme,但它是 LISP1,因此空列表规则不能与 Lisp1 与 Lisp2 有关,因为 Scheme 是第一个报告中的 Lisp1,不需要引用并且具有nil错误值。

对于报告的每个连续版本,Scheme 都在改进其语法和命名转换。修订版做了细微的改变,他们不怕做出重大改变。他们引入了新的布尔值,更改了它们的名称,将空列表的布尔值从 false 更改为 true,删除了nilandt作为 and 的别名,#t#f认为()是无效的表达式,因此需要'().

因为在 CL 中如何做并不重要,也许一些用两种语言编写代码的人只是想在他们的生活中保持一些对称性。我当然会这样做,但我不能代表所有的阴谋家。

于 2016-05-24T23:46:48.360 回答