第1章振り返り

手続きの抽象がメインテーマと言うことで、Square Rootの定義を振り返ってみましょう。

定義(p.12)
(define (sqrt x)
  (the y (and (>= y 0)
              (= (square y) x))))

yが0以上でかつ2乗するとxになるもの

と言う定義をそのままS式にしてみました、って感じ。
でも、これも結構奥が深いらしくて、このような平叙文で書くと、それを自動的に命令文に変える、とかっていう研究が昔盛んに行われてたそうだ。
確かに、定義をそのまま書けると素敵だ。偏微分方程式を定義すると、それを解いてくれる、みたいな。

命令文的記述(p.13)
(define (sqrt x)
  (define (sqrt-iter guess x)
    (if (good-enough? guess x)
	guess
	(sqrt-iter (improve guess x)
         	   x)))
  (define (improve guess x)
    (average guess (/ x guess)))
  (define (good-enough? guess x)
    (< (abs (- (square guess) x)) 0.001))
  (iter 1.0 x))

上記の定義式を反復法で記述したもの。コンピュータには、命令を与えてやらないといけない、と言うことですね。

Fixed-Point版1(解が振動するやつ) (p.39)
(define (sqrt x)
  (fixed-point (lambda (y) (/ x y))
           1.0))

x(n+1) = k / x(n) と言う更新式にしたやつ。
ここでのミソは、平方根を求めると言うプロセスを不動点を求める、と言う一般的な手続きに置き換えたこと。
sqrtの場合には、同じ点をぐるぐる回るだけで、収束しません。

Fixed-Point版2(緩和法を組み込んだもの) (p.39)
(define (sqrt x)
  (fixed-point (lambda (y) (average y (/ x y)))
	   1.0))

x(n+1) = (x(n) + k/x(n))/2 と言う更新式にしたやつ。移動量を減らしたことになります。これで不動点に収束します。

Fixed-Point版3(平均緩和の汎用化) (p.41)
(define (average-damp f)
  (lambda (x) (average x (f x))))
(define (sqrt x)
  (fixed-point (average-damp (lambad (y) (/ x y)))
			   1.0))

この辺から、段々鬼畜化して行く感じ。手続きを返す、と言うものが出てくると、頭が混乱してくる。
これは、平均緩和法は汎用的に使えるので、average-dampと言う手続きを作っちゃおう、と言うことですね。

Newton法でWrapした版 (p.42)
(define (newtons-method g guess)
  (fixed-point (newton-transform g) guess))
(define (newton-transform g)
  (lambda (x)
	(- x (/ (g x) ((deriv g) x)))))
(define (sqrt x)
  (newtons-method (lamba (y) (- (square y) x))
		  1.0))

今度は、Newton法は、不動点を求めるプロセスの専用化であり、さらに、平方根を求めるプロセスはNewton法の専用化だよね〜、と言うこと。

抽象化最強 (p.43)
(define (fixed-point-of-transform g transform guess)
  (fixed-point (transform g) guess))
(define (sqrt x)
  (fixed-point-of-transform (lambda (y) (/ x y))
   			    average-damp
			    1.0))
(define (sqrt x)
  (fixed-point-of-transform (lambda (y) (- (square y) x))
			    newton-transform
			    1.0))

鬼畜過ぎ。でも、抽象化の壁がちゃんとしているため、コード自体は見やすい。でも、動作を追っかけるのは難しい。


結局、ぼくらは仕事をする上で、常に抽象化を考えているわけだけど、抽象化の仕方によって、きれいなインターフェースができたり、とんでもないインターフェースになったりする。APIを作る時には、いつも一貫性の取れたインターフェースになるように、適切な抽象化をしないと行けない。

この本は、ぼくに抽象化の難しさを教えてくれている、気もする。