我不明白为什么我们需要nil
[1] 何时cons
项目序列(所谓的正确列表)。在我看来,我们可以通过使用所谓的不正确列表来实现相同的目标(cons
-ed 对没有结尾nil
) 独自的。由于 Lisps [2] 已经提供了一个原始过程来区分pair?
和一个原子(一些实现甚至提供atom?
),在列表上定义过程时,例如,length
,我可以对点对做同样的事情,如下所示:
(define len
(lambda (l)
(cond ((pair? l) (+ 1 (len (cdr l))))
(else 1) ) ) )
显然,我们可以将此过程应用于不正确的列表,例如'(1 . (2 . 3))
得到预期的答案3
,与传统的(length '(1 2 3))
.
我想听听任何支持必要性的意见nil
。提前致谢。
[1] 让我们忽略之间的争论nil
/NIL
, '()
and ()
.
[2] 这里指的是 Lisp 语言家族。
使用列表而不需要nil
(or '()
) 就像做没有零的算术一样。仅使用对没有nil
,我们如何表示一个空列表或一个单例列表'(1)
?
情况变得更糟:由于列表不必是原子列表,而是可以包含其他列表,我们将如何表示嵌套列表'(1 2 (3 4))
?如果我们进行以下转换:
'(3 4) => '(3 . 4)
'(1 2 x) => '(1 . (2 . x)) == '(1 2 . x)
we get:
'(1 2 (3 4)) => '(1 . (2 . (3 . 4))) == '(1 2 3 . 4)
但是也:
'(1 2 3 4) => '(1 . (2 . (3 . 4))) == '(1 2 3 . 4)
因此仅使用对构建列表而不使用nil
阻止我们区分嵌套列表结构和平面列表,至少在列表末尾。您仍然可以将嵌套列表作为除最后一个元素之外的任何元素包含在内,因此现在列表的元素可以是什么有一个奇怪且任意的限制。
更理论上来说,真列表是一种归纳定义的数据类型:列表要么是空列表,要么有一个first
元素,可以是任何东西,以及rest
,即always以相同方式定义的另一个列表。去掉空列表,现在你有一个数据类型,其中rest
might是另一个列表,或者可能是列表的最后一个元素。我们无法判断,除非将其传递给pair?
,这导致了上面嵌套列表的问题。保持nil
around 让我们可以将任何我们喜欢的列表元素作为列表元素,并允许我们区分1
, '(1)
, '((1))
等等。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)