SBCL中为何'(nil . nil)求值为(nil)而非nil?
关于SBCL中
'(nil . nil)与'()的差异问题 在SBCL的REPL中,输入'(nil . nil)会得到(nil)而非nil,明明空列表'()的car和cdr都是nil,'(nil . nil)的car和cdr也都是nil,为什么二者不相等?
你推测的这些求值结果是正确的:
(car '()) => nil (cdr '()) => nil (car '(nil . nil)) => nil (cdr '(nil . nil)) => nil
但实际运行结果确实是:
'() => nil '(nil . nil) => (nil)
核心原因:空列表与cons单元的本质区别
在Common Lisp里,合法列表的定义是二元的:
- 要么是
nil(空列表),它是一个独立的特殊对象,不属于cons单元(用(consp '())验证会返回nil); - 要么是一个
cons单元,且它的cdr部分必须也是一个合法列表(可以是nil,也可以是另一个符合要求的cons单元)。
'(nil . nil)是一个标准的cons单元:它的car是nil,cdr是nil(而nil是合法列表),所以REPL会把它识别为合法列表,并用列表格式(nil)打印出来——只有当cons单元的cdr不是合法列表时,REPL才会显示成点对形式(比如'(a . b))。
而'()本身就是空列表,它不是cons单元,所以和'(nil . nil)是完全不同的对象,自然不相等。你可以通过比较验证:
(eq '() '(nil . nil)) ; 返回 nil (equal '() '(nil . nil)) ; 同样返回 nil
内容的提问来源于stack exchange,提问作者Galladite
相关产品推荐
相关产品推荐

