cons and list
atom
序言中定义了 atom?:
(define atom?
(lambda (x)
(and (not (pair? x)) (not (null? x)))))
即,不是 pair,也不是 null 的东西就叫 atom
> (atom? null)
#f
> (atom? '(1 2 3))
#f
> (atom? #f)
#t
> (atom? 1)
#t
> (atom? "abc")
#t
怀疑这是不是书中自造的概念,我在 The Racket Guide 里没看到这个说法
pair, list 和 s-expression
reference 中提到:
In general, the result of cons is a pair. The more traditional name for the cons? function is pair?, and we’ll use the traditional name from now on.
也就是说 cons 是 pair 的构造子,(cons a b) 表示把 a 和 b 连在一起,构成一个 pair。
这一点与书中不一样。
TLS中并没有pair这一回事,而是只有list,并将cons视为list的构造子,其第二个参数必须也是一个list。我这里还是采用
racket实际的情况。对此,书中提到一笔:
In practice,
(cons a b)works for all valuesaandb, and
(car (cons a b)) = a,(cdr (cons a b)} = b
利用 cons,我们构造出 list 和 s-expression,按我理解,二者是递归定义的,以 CFG 写出来大概像这样:
S-expression =
atom |
list
list =
null |
(cons S-expression list)
list
- 要么是
null - 要么是一个特殊的
pair。特殊在于该pair的第二个部分一定是一个list。由此可知,list必有类似以下的结构:
(cons a (cons b (cons c (cons d null))))
一个例子是
> (cons null null)
'(())
racket 中,null 也可以写作 '()。单引号是一个函数 quote 的简写
值得注意,(cons a b) 直接将 a, b 组成一个 pair,这不等于 (list a b):
> (cons 1 2)
'(1 . 2)
> (cons 1 '(2))
'(1 2)
> (list 1 2)
'(1 2)
> (list? (cons 1 2))
#f
> (pair? (cons 1 2))
#t
> (pair? (list 1 2))
# t
'(a b) 表示一个 list,而 '(a . b) 表示一个 pair。应该将前者看作后者的一种简写,'(a b) 写全了应该是 '(a . (b . ()))
quote
还需理解
datum。quote是否与其数据引用有关。
'a = (quote a)
'(a b c) = (list 'a 'b 'c)
在 REPL 里测试一下:
> '#t
#t
> '1
1
> '"abc"
"abc"
> '()
'()
> (list)
'()
> 'fdasfs
'fdasfs
一个层层展开的例子:
''(1)
-> (quote '(1))
-> (quote (quote (list 1)))
> (car ''(1))
'quote
> (cdr ''(1))
'((1))
分析一下,首先,要理解 (car ''(1)) 得到 'quote ,只需要理解 (quote (quote (list 1))) 是一个 list,它的左侧就是 quote
然后为了得到 (cdr ''(1)),这里把 list 看成 pair,即:
(quote (quote (list 1)))看作(quote . ((quote (list 1))))
再例如:
> (car '(define a 1))
'define
> (car '(+ 1 2))
'+
这里有个关于 null 的,有点特别的例子:
> null
'()
> '()
'()
> 'null
'null
> ''()
''()
> ''null
''null
null
书中指出,(quote ()) 是 null 的一种记号。
Lisp: Also
()and'().Scheme: Also
'()
实验一下:
> (quote ())
'()
> (null? (quote ()))
#t
嗯... () 能单独出现在 (quote ()) 里,这是否说明解释器以某种规则进行了特判。
> null
'()
> '()
'()
> (eq? null '())
#t
> (eq? 'null ''())
#f
有点神秘