続・SICP問題1.6

昨日の無限ループに入る問題。

http://d.hatena.ne.jp/xiombatsg/20060626#p1

であれから考えたが、結論がわかれば大したことは無かった。

(define (new-sqrt-iter y x)
   (new-if (good-enough y x)
         y
         (new-sqrt-iter (improve y x) x)))

やはりこれが問題。
まず、

(new-sqrt-iter y x)

が展開されると

(new-if (good-enough y x) y (new-sqrt-iter (improve y x) x)))

となるわけだが、
これを展開するときに

new-if good-enough new-sqrt-iter improve x y

が全部展開される。
この時に

new-sqrt-iter

の展開でループに入ってしまうのだ。

(define (sqrt-iter y x)
        (if (good-enough y x)
             y
            (sqrt-iter (improve y x) x)))


Schemeの特性上必要な時に必要な展開を行うので

(if (good-enough y x) y (sqrt-iter (improve y x) x)))

とすると、

(good-enough y x)

が、falseになった時だけ

(sqrt-iter (improve y x) x)

を展開するので正常に動作する。