'() vs () in Common Lisp



在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))的原因。两者都评估了同一件事,但前者在视觉上很明显,foobarbaz(+ 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中做到这一点并不重要,也许一些用两种语言编码的人只是想在他们的生活中有一些对称性。我当然这样做,但我不能代表所有阴谋家。

相关内容

  • 没有找到相关文章

最新更新