Мы можем использовать модель замещения.
(better-sqrt 1)
(better-sqrt-iter 0 1.0 1)
(cond
((better-good-enough? 0 1.0) 1.0)
(else
(better-sqrt-iter 1.0
(improve 1.0 1)
1))))
(cond
(#f 1.0)
(else
(better-sqrt-iter 1.0
(improve 1.0 1)
1))))
(better-sqrt-iter 1.0
(improve 1.0 1)
1)
(better-sqrt-iter 1.0
1.0
1)
(cond
((better-good-enough? 1.0 1.0) 1.0)
(else
(better-sqrt-iter 1.0
(improve 1.0 1.0)
1))))
(cond
(#t 1.0)
(else
(better-sqrt-iter 1.0
(improve 1.0 1.0)
1))))
1.0
Теперь давайте попробуем то же самое с new-if
:
(better-sqrt 1)
(better-sqrt-iter 0 1.0 1)
Схема говорит, что вы можете оценивать процедуры в любом порядке.Я выбираю справа налево!
(new-if (better-good-enough? 0 1.0)
1.0
(better-sqrt-iter 1.0
(improve 1.0 1)
1))
(new-if (better-good-enough? 0 1.0)
1.0
(new-if (better-good-enough? 1.0 1.0)
1.0
(better-sqrt-iter 1.0
(improve 1.0 1)
1)))
(new-if (better-good-enough? 0 1.0)
1.0
(new-if (better-good-enough? 1.0 1.0)
1.0
(new-if (better-good-enough? 1.0 1.0)
1.0
(better-sqrt-iter 1.0
(improve 1.0 1)
1))))
(new-if (better-good-enough? 0 1.0)
1.0
(new-if (better-good-enough? 1.0 1.0)
1.0
(new-if (better-good-enough? 1.0 1.0)
1.0
(new-if (better-good-enough? 1.0 1.0)
1.0
(better-sqrt-iter 1.0
(improve 1.0 1)
1)))))
;; goes on like this forever!
Обратите внимание, что мне никогда не удается выполнить ни один из вызовов good-enough
, поскольку все 3 выражения необходимо завершить до тела new-if
может быть вычислено, тогда как встроенный if
сначала оценивает тестовое выражение, а затем оценивает только одно из последующего или альтернативного выражения, основываясь на результате оценки тестового выражения, иТаким образом, рекурсия останавливается.