2.4 Multiple Representations for Abstract Data
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-17.html#%_sec_2.4
複素数の表現を題材に、
- 明確な振り分け
- データ主導
- メッセージパッシング
の3つのAdditiveな手法を学ぶ、と言うのが本節の主題。
問題自体は少ないのだけど、この節は実際のプログラムを作る上で非常に重要な気がする。
何かのシステムを作る時には、たいていオプションという形で選択肢を容易するわけだが、内部でどのようにオプションによって処理を切り分けるべきか、というのは、結構悩む。結局、if-elseでやってる場合が多いのだけど(明確な振り分け)、他の手法を採用してみてもいいかもしれない。
問題2.73
a. タグが付いてないから。逆に言うと、タグを付ければいい。
b.
(define (install-deriv) ;;; Internal Procedure (define (sum exp var) (make-sum (deriv (addend exp) var) (deriv (augend exp) var))) (define (product exp var) (make-sum (make-product (multiplier exp) (deriv (multiplicand exp) var)) (make-product (deriv (multiplier exp) var) (multiplicand exp)))) (define (exponent exp var) (make-product (make-product (exponent exp) (make-exponentiation (base exp) (- (exponent exp) 1)) (deriv (base exp) var)))) ;;; Interface (put 'deriv '+ sum) (put 'deriv '* product) (put 'deriv '** exponent) 'done)
d. putの第1引数と第2引数を入れ替えれば良い
問題2.74
よくわからんので飛ばす。
問題2.75
(define (make-from-mag-ang r a) (define (dispatch op) (cond ((eq? op 'magnitude) r) ((eq? op 'angle) a) ((eq? op 'real-part) (* r (cos a))) ((eq? op 'imag-part) (* r (sin a))) (else (error "Unkown op -- MAKE-FROM-MAG-ANG" op)))) dispatch)
問題2.76
この問題がこの節の一番重要なところな気がする。
3つの手法(明確な振り分け、データ主導、メッセージパッシング)のPros and Cons
とりあえず、ぼくなりの解。
新しい型の追加 | 新しい演算の追加 | システムの変更 | |
明確な振り分け | 全ての手続きを名前がバッティングしないように変更 | 演算手続きを追加 | 大 |
データ主導 | 新しい型のパッケージを追加 | 各パッケージに新しい演算を追加 | 中 |
メッセージパッシング | ディスパッチオブジェクトを追加 | ディスパッチャに演算を追加 | 小 |
と言ったところかな。
システム側の変更が最も小さい、と言う点では、メッセージパッシングが最も有効なのだろうか。
でも、データ主導の方がメンテナンスはやりやすそう。