[Back]

2.4 抽象数据的多重表示

2.73

; A)num? 和 variable? 谓词都是在数据层面的判断,而不是在数据操作层面的谓词,因此不能安装到表内,
;    因为他们对所有数据类型具有通用性。
; B) 
(define (install-add-package)
    (define (addend x) (car (cdr x)))
    (define (augend x) (car (cdr (cdr x))))
    (define (make-sum a1 a2)
        (cond ((=number? a1 0) a2)
              ((=number? a2 0) a1)
              ((and (number? a1) (number? a2)) (+ a1 a2))
              (else (tag (list a1 a2)))))
    (define (deriv-plus object var)
        (make-sum (deriv (car object) var)
                  (deriv (car (cdr object)) var)))
    (define (tag x) (attach-tag `+ x))
    (put `deriv `+ deriv-plus)
    (put `make-sum `+ make-sum)
    `done)
(define (install-multiply-package)
    (define (multiplier p) (car (cdr p)))
    (define (multiplicand p) (car (cdr (cdr p))))
    (define (make-product a1 a2)
        (cond ((or (=number? a1 0) (=number? a2 0)) 0)
              ((=number? a1 1) a2)
              ((=number? a2 1) a1)
              ((and (number? a1) (number? a2)) (* a1 a2))
              (else (tag (list a1 a2)))))
    (define (deriv-multi object var)
        ((get `make-sum `+) (make-product (car expr) (deriv (car (cdr expr)) var))
                            (make-product (car (cdr expr)) (deriv (car expr) var))))
    (define (tag x) (attach-tag `* x))
    (put `deriv `* deriv-multi)
    (put `make-product `* make-product)
    `done)

; C)
(define (install-exp-package)
    (define (base x) (car (cdr x)))
    (define (exponent x) (car (cdr (cdr x))))
    (define (make-exp a1 a2)
        (cond ((=number? a2 1) a1)
              ((=number? a2 0) 1)
              ((and (number? a1) (number? a2)) (exp a1 a2))
              (else (tag (list a1 a2)))))
    (define (deriv-exp object var)
        ((get `make-product `*) (exponent expr)
        ((get `make-product `*) (make-exp (base expr) ((get `make-sum `+) (exponent expr) (- 1)))
        (deriv (base expr) var))))
    (define (tag x) (attach-tag `** x))
    (put `deriv `** deriv-exp)
    (put `make-exp `** make-exp)
    `done)

; D)
; 只需修改每个安装包的put函数即可

2.74

简要的说一下这道题目(因为代码量实在太大了)

A) 只需要提供各个分支机构实现集合的方法,这样我们就能在安装了集合表示包的表中寻找到能够查询的方法。

B) 同A

C) 同A

D) 显然数据导向的通用型操作不需要修改,只需要安装新的人事文件的表示方法就行了。

2.75

(define (make-from-mag-ang mag ang)
    (define dispatch op)
        (cond ((eq? op `real-part) (* mag (cos ang)))
              ((eq? op `imag-part) (* mag (sin ang)))
              ((eq? op `magnitude) x)
              ((eq? op `angle) y)
              (else (display "Unknown op -- MAKE-FROM-MAG-ANG" op)))
    dispatch)

2.76

显式分派的通用性操作,每次安装一个操作或者类型,都要修改所有的通用性操作,十分的麻烦。

数据导向的通用型操作,每次安装一个操作时,并不需要修改其他什么,每次安装一个类型时,需要修改分派表的结构。适合安装过程。(安装类型其实也没有修改,但有效率上的损失。)

消息传递的数据类型,每次安装新操作都要修改所有数据类型,安装新类型,则不需要修改什么,适合安装类型。