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

とりあえず、ぼくなりの解。

新しい型の追加 新しい演算の追加 システムの変更
明確な振り分け 全ての手続きを名前がバッティングしないように変更 演算手続きを追加
データ主導 新しい型のパッケージを追加 各パッケージに新しい演算を追加
メッセージパッシング ディスパッチオブジェクトを追加 ディスパッチャに演算を追加

と言ったところかな。

システム側の変更が最も小さい、と言う点では、メッセージパッシングが最も有効なのだろうか。
でも、データ主導の方がメンテナンスはやりやすそう。