一人読書会 「計算機プログラムの構造と解釈」 (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 のどちらかしか評価しないのだ。
なるほど。