source code
#lang planet neil/sicp
(define (mycons x y)
(define (set-first aim-data) (set! x aim-data))
(define (set-second aim-data)(set! y aim-data))
(define (dispatch m)
(cond ((eq? m 'car) x)
((eq? m 'cdr) y)
((eq? m 'set-car!) set-first)
((eq? m 'set-cdr!) set-second)
(else (error "wrong paramter of cons!"))))
dispatch
)
(define (car z) (z 'car))
(define (cdr z) (z 'cdr))
(define (set-car! z aim-value) ((z 'set-car!) aim-value))
(define (set-cdr! z aim-value)((z 'set-cdr!) aim-value))
(define pair (mycons 'a 'b))
(car pair)
(cdr pair)
(set-car! pair 'gao)
(car pair)
(set-cdr! pair 'duan)
(cdr pair)
分析mycons
- 首先看mycons函数,它是一个典型的数据导向的分派函数:具体来说,它返回的是一个叫做dispatch的函数,而这个函数可以接受一些参数比如 'car等来调用新的函数实现功能;
- 这也是用过程来实现数据结构的一个实例,scheme 刷三观的地方很多,关于过程是最为集中的一块,比如函数表达数据,函数表达这里的数据结构等等;
cons的本质就是构建一个pair,不管什么方式把他们结合在一起都可以,只要car z的时候可以返回first number,cdr z的时候返回second number就可以了 - 内部的car 和 cdr是查询过程,返回值就可以了;而set-car!、set-cdr!是要对数据改变的操作,并且还需要额外的参数,所以这里多了一层分派;
操作函数
-
有了mycons之后,相当于用户使用cons x y 之后,他有了一个dispatch函数,这显然还不够,更重要的是提供接口,查询和改变的接口:
-
这里的接口有两类,首先是car cdr函数,其次是set-car!、set-cdr!函数;
-
我们实际使用的时候无需关心实现的细节,还是十分便捷;
其它
- sicp 的一个小例子,涉及了第二章的数据表示,以及第三章的赋值和改变,也包括第二章抽象的一些手法。