一人読書会 「計算機プログラムの構造と解釈」 (3)
1.1.7 Newton 法による平方根
Newton法 により平方根を求める手続きを実装する。
問題 1.6
ifは特殊形式であるが、cond を利用して普通の手続きとして定義し、平方根の計算にこれを使おうとすると何が起きるか。
以下、特殊形式の if を 通常の手続きである、new-if を定義し、平方根を Newton法 で求める処理を書き直した。
(define (square x) (* x x))
(define (sqrt-itr guess x)
(new-if (good-enugh? guess x)
guess
(sqrt-itr (improve guess x)
x)))
(define (improve guess x)
(avarage guess(/ x guess)))
(define (avarage x y)
(/ (+ x y) 2))
(define (good-enugh? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (sqrt2 x)
(sqrt-itr 1.0 x))
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
実際に動かしてみると、スタックオーバーフローだろう、Out Of Memory が発生した。
特殊形式 if を使った場合には、想定通りの動きをしていた。ぱっと見、等価に思えるが。
うーーん 。。。 なぜだろう 。。。
・・・
特殊形式・・・ define は 特殊形式で、作用は行わない。。。 if も特殊形式・・・
通常評価は、部分式を評価し、作用(演算子を適用)させる・・・
おお!そうか、特殊形式ではないから、被演算子がすべて評価されてしまうからか!、sqrt-itr の else 節 で、再帰しているのが、終了条件に合致しても、else節 がなんと、評価されてしまうのだ!
if は特殊形式で、条件に合致した then または、 else のどちらかしか評価しないのだ。
なるほど。

