SICP – [6] 第1章 手続きによる抽象の構築 12-14 ページ

2007 年 4 月 16 日 | カテゴリー: プログラム

間が空いたというのもあるものの、1問を解くのでいっぱいいっぱい。
1.5 でなるほどと感じたところが、さっそく 1.6 でも要求されました。

問題1.6

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

Gauche で実行すると無限ループらしく止まりません。

gosh> (sqrt-iter 1 2)
CALL sqrt-iter 1 2
CALL sqrt-iter 1.5 2
CALL sqrt-iter 1.4166666666666665 2
CALL sqrt-iter 1.4142156862745097 2

1つずつ展開しながら考えてみます。

(sqrt-iter 1 2) を展開。

(new-if (good-enough? 1.0 2)
1
(sqrt-iter (improve 1.0 2)
2)))

new-if の引数が評価される。

(new-if #f
1
(sqrt-iter 1.5 2))

(sqrt-iter 1.5 2)) を展開。

(new-if #f
1
(new-if (good-enough? 1.5 2)
1.5
(sqrt-iter (improve 1.5 2))))

以下略。

(new-if #f
1
(new-if #f
1.5
(sqrt-iter 1.4166666666666665 2)))
(new-if #f
1
(new-if #f
1.5
(new-if #f
1.4166666666666665
(sqrt-iter 1.4142156862745097 2))))

1.5 のときは if で #t がくれば終わったけれど、1.6 の new-if のように実現しようとすると、new-if の引数として与えられた then-clause と else-clause はその時点で両方評価されてしまうので再帰的に無限ループに陥るみたい。

今は上記のメモで理解できるけど、今後の自分が忘れたころにこの説明を読んで理解できるかは少し自信ない。

コメントはまだありません。