为什么我们需要`nil'? [英] Why do we need `nil`?
问题描述
我不明白为什么要cons
项目序列(所谓的正确列表)时需要nil
[1].在我看来,我们可以通过单独使用所谓的不正确列表(cons
-ed对而没有结尾nil
)来实现相同的目标.由于Lisps [2]已经提供了区分pair?
和原子的原始过程(某些实现甚至提供了atom?
),因此在列表中定义过程(例如length
)时,我可以执行相同的操作只是点对,如下所示:
I do not see why we need nil
[1] when to cons
a sequence (so-called proper list) of items. It seems to me we can achieve the same goal by using the so-called improper list (cons
-ed pairs without an ending nil
) alone. Since Lisps [2] have already provided a primitive procedure to distinguish between a pair?
and an atom (some implementations even provide atom?
), when defining a procedure on a list, e.g., length
, I can do the same with just dotted-pairs, as shown below:
(define len
(lambda (l)
(cond ((pair? l) (+ 1 (len (cdr l))))
(else 1) ) ) )
很明显,与传统的(length '(1 2 3))
相比,我们可以将此过程应用于诸如'(1 . (2 . 3))
的不正确列表以获得预期的答案3
.
It is obvious that we can apply this procedure to an improper list like '(1 . (2 . 3))
to get the expected answer 3
, in contrast to the traditional (length '(1 2 3))
.
我想听听任何有关nil
必要性的意见.预先感谢.
I'd like to hear any opinions in defense of the necessity of nil
. Thanks in advance.
[1]让我们忽略nil
/NIL
,'()
和()
之间的争论.
[1] Let's ignore the debate among nil
/NIL
, '()
and ()
.
[2]这里表示Lisp语言家族.
[2] Here it means the Lisp family of languages.
推荐答案
使用不带nil
(或'()
)的列表就像执行不带零的算术运算.仅使用不带nil
的对,我们将如何表示一个空列表或单例列表'(1)
?
Working with lists without nil
(or '()
) would be like doing arithmetic without zero. Using only pairs without nil
, how would we represent an empty list, or a singleton list '(1)
?
情况变得更糟:由于列表不必一定是原子列表,但可以包含其他列表,我们将如何表示嵌套列表'(1 2 (3 4))
?如果我们进行以下转换:
It gets worse: since lists don't have to be lists of atoms, but can contain other lists, how would we represent the nested list '(1 2 (3 4))
? If we do the following conversions:
'(3 4) => '(3 . 4)
'(1 2 x) => '(1 . (2 . x)) == '(1 2 . x)
我们得到:
'(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
构造列表将阻止我们区分嵌套列表结构和平面列表,至少在列表的末尾.您仍然可以将嵌套列表作为除最后一个元素之外的任何元素包括在内,因此现在列表的元素可以是一个奇怪而任意的限制.
So constructing lists only using pairs and no nil
prevents us from distinguishing between a nested list structure and a flat list, at least at the end of the list. You can still include nested lists as any element except the last, so now there's a strange and arbitrary limitation on what the elements of a list can be.
从理论上讲,适当的列表是一种归纳定义的数据类型:列表是空列表,或者具有first
元素(可以是任意值)和rest
总是 以相同方式定义的另一个列表.拿走空列表,现在您有了一个数据类型,其中rest
可能是另一个列表,或者它可能是列表的最后一个元素.除了将其传递给pair?
,我们无法分辨,这导致了上面的嵌套列表的问题.保持nil
不变,我们可以将自己喜欢的任何东西用作列表元素,并可以区分1
,'(1)
,'((1))
等.
More theoretically, proper lists are an inductively defined data type: a list is either the empty list, or it has a first
element, which can be anything, and a rest
, which is always another list defined in the same way. Take away the empty list, and now you have a data type where the rest
might be another list, or it might be the last element of the list. We can't tell except by passing it to pair?
, which leads to the problem with nested listing above. Keeping nil
around lets us have whatever we like as list elements, and allows us to distinguish between 1
, '(1)
, '((1))
and so on.
这篇关于为什么我们需要`nil'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!