level 1
请问scheme cons 两个元素后为什么有个点
如果(cons 1 2)
则得到(1 . 2)
如果(cons 1 (cons 2 `()))
则得到(1 2)
请问scheme为什么这么设计?弄个点恶心人吗?
还有scheme教程里经常有
讲解(1 . (2 . (3. `())))
能得到(1 2 3)的这个规则
可是这个规则有什么用?
这和cons表达出来的意思有什么不一样的吗,
这是要给cons 起个点的别名再重复一遍
2017年05月07日 14点05分
1
level 1
cons 是用来构造pair数据的, 而数据的内容是一对元素;
car和cdr是pair的提取函数,其中car提取第一个元素,cdr提取第二元素。
list是一系列的pair复合(所以pair更基本),但list更常用,为了区分它们记号上牺牲了pair(用点来标记了)。
2017年08月05日 13点08分
4
level 4
1
cons用来构造点对(pair, 或称dot pair),(cons 1 2)就得到了点对(1 . 2).它只有两个部分,前面部分叫做car部分,后面部分叫做cdr部分。cons可以叠加,比如你(cons 3 (cons 1 2)) 就得到
=> (cons 3 (1 . 2)) 可以简写为 => (3 1 . 2)
在某些标准的实现(或称解释器)里面,可以用(car ...) 和(cdr ...)两个函数得到这两部分。
(car (1. 2)) => 1
(cdr (1. 2)) => 2
(cdr (3 1 . 2)) => (1. 2)
所以你看到的那些 形如(x1 x2 ... xl xm xn . xo) 这种最后一个元素前面加了个点的东西,都可以看成是很多次cons运算的结果。这个东西它不叫表,按R5RS标准,它叫“非严格表”。也就是说有表的一些性质,但不那么严格。
2
要定义表,就要先定义空表。空表的外部表现是'( ), 它是一个属于自身的特殊数据类型。
表(list)可以通过递归方法来定义:表是这样的东西,要么它是个空表,要么它的cdr部分是个表。
依照这个定义,我们发现,每个表的最右边一个元素都必须是空表。(这个你可以多思考下,注意递归)
所以,其实所有的表都应该是这样的长相'(x1 x2 ... xn '( ))。显然,长成这样子的东西,也可以从很多个cons得到,比如你(cons 4 (cons 3 (cons 2 (cons 1 '())))), 就能得到
=> (4 . (3 . (2 . (1 . '()))))
这个东西也可以简写成
=> (4 3 2 1 . '())
可以看到,这个东西满足表的定义,(无论是从长相上还是从文字定义上),所以它就是个表。
3
现在来比较一下两个东西
(cons 3 (cons 2 1)) => (3. (2. 1)) => (3 2 . 1) 这个是非严格表。
(cons 3 (cons 2 (cons 1 '( )))) => (3 . (2. (1 . '( )))) => (3 2 1 . '()) 这个是表,或说严格表。
4
一般我们要定义一个表,有两种方式
第1,用list, (list 1 2 3) 返回表 (1 2 3), 实际上它是(1 2 3 . '()).你也许会问,它不把空表写出来,不是跟非严格表一样了吗?当然不,如果是压根没有后面空表的非严格表,它会写成(1 2 . 3),必定有那个点。
第2,用quote,(quote (1 2 3))就返回(1 2 3),由于quote用的太多,也简写成 ' ,即
(quote (1 2 3)) <=> '(1 2 3)
所以定义一个表往往是(define L (list 1 2 3)) 或者(define '(1 2 3)).
后面还会遇到准引用(quasiquote),代替它的符号是`,就是英文状态下按左上角esc下面那个键。准引用与引用的作用有所区别,这里就不讲了。
2019年05月22日 11点05分
6
倒数第三行字打掉个L,(define L '(1 2 3))
2019年05月22日 11点05分
level 6
(1 2)
和(1 . 2)
是不一样的东西
点说白了是一种表示序偶(pair)的方式,或者你有其他方案表示觉得比它更好,也可以提出来
2019年05月24日 05点05分
7