今天在看SICP 的时候发现一个问题,2.2.2层次性结构,构造一个 (cons (list 1 2) (list 3 4)) ,输出的结果 ((1 2) 3 4) ,想象中的结果应该是 ((1 2) (3 4)) 才对啊。
我们知道,构造一个表 (list 1 2 3 4) 等价于 (cons 1 (cons 2 (cons 3 (cons 4 nil)))) ,精简一下 (list 1) 等价于 (cons 1 nil) 。nil表示不包含任何元素的空表。也就是说 表 list 是一个以 nil 结尾的特殊的 序对 pair 。
回到刚开始的问题, (cons (list 1 2) (list 3 4)) 等价于 (cons (cons 1 (cons 2 nil)) (cons 3 (cons 4 nil))) ,因为以nil结尾,所以该表达式返回的是一个list,而 (cons 1 (cons 2 nil)) 也就是表 (1 2) , 是返回的表中的第一个元素,而3是第二个元素,4是第三个元素,返回表的长度是3。
对比看一下, (list (list 1 2) (list 3 4)) 等价于 (cons (list 1 2) (cons (list 1 2) nil)) 等价于
(cons (cons 1 (cons 2 nil)) (cons (cons 3 (cons 4 nil)) nil)) ,表示式返回值为 ((1 2) (3 4))
也就是说 返回的表是由表 (1 2) 和 表 (3 4)组成的,长度为2。
注意:在 chez scheme 的解释器中nil空表要用 '() 表示。
这里我突然想构造一个空表,于是在解释器里尝试了以下方法,
这里你会发现直接用 '() 或者 (list) 都能构造一个空表,但是用 (cons '() '()) 却返回一个包含空表的空表(返回的表长度为1),我这又有疑问了,'()空表到底是怎么实现的?
google了一下 http://deathking.github.io/yast-cn/contents/chapter3.html ,发现Cons单元(Cons cells)外,还有一种更简单的数据类型叫原子Atom。不使用Cons单元的数据结构就叫原子,其中空表 '() 即是表,又是原子。(关键字 lisp的7个公理 https://zh.wikipedia.org/wiki/LISP)