Common Lisp:普通变量是LET中列表的简写?

Reb*_*bin 6 common-lisp practical-common-lisp

我正在阅读Gigamonkey(Peter Seibel的)Practical Common Lisp,并在Macros章节中关于DO的部分中遇到了以下声明:

与LET中的变量定义一样,如果省略init-form,则变量绑定到NIL.与LET一样,您可以使用普通变量名作为仅包含名称的列表的简写.

我不知道他的意思是"使用普通变量作为缩写,只包含名称的列表",即第二句.第一句是在LETCommon-Lisp Hyperspec中备份的,通过一个简单的例子(let (n) n) ~~> NIL,但我找不到与第二句相对应的任何内容.事实上,像是(let n n)一个SBCL编译器.

这是什么意思?这个用法的最小例子是什么?

Jos*_*lor 14

这是什么意思?

它只是意味着所有这三个都具有相同的效果:

(let ((x nil))      (let ((x))        (let (x)
  x)                  x)                x)
Run Code Online (Sandbox Code Playgroud)

在每种情况下,x都绑定为nil.大多数人都熟悉第一种情况.第二种情况不包括init-form,但Common Lisp也被定义为在这种情况下将x绑定到nil.当然,第二种情况,以一种方式来看,它有你需要的更多括号(它只是变量周围的一组额外的括号),所以你甚至可以采取另一种快捷方式,只需自己编写变量.

它在哪里指定?

let的文档中,我们看到let的语法是:

let({var |(var [init-form])}*)声明*表格*⇒结果*

从那以后,我们看到let的每次使用都会看起来像

(let (…) …)
Run Code Online (Sandbox Code Playgroud)

但内心清单是什么呢?

{var | (var [init-form])}*

*表示该列表中可以有任意数量(零个或多个),并且每个都匹配var(var [init-form]).var只是一个可以用作变量的符号.的(VAR [INIT-形式])是具有一个列表变种作为第一元件,和任选地具有第二元件,所述INIT-形式.

但这意味着在两种可能的情况下(var all本身,而没有init-form的列表)没有init-form.Common Lisp不是拥有未绑定或未初始化的变量,而是将这些情况下的值定义为nil.

为什么允许这么多的变化?很多是Common Lisp中不同特殊形式之间的一致性.看一下Issue VARIABLE-LIST-ASYMMETRY Writeup.有关阅读文档中语法规范的更多信息,请查看1.4.4.20词典条目的"语法"部分.