Exercise 1.6. Alyssa P. Hacker doesn’t see why if needs to be provided as a special form. ‘‘Why can’t I just define it as an ordinary procedure in terms of cond?‘’ she asks. Alyssa’s friend Eva Lu Ator claims this can indeed be done, and she defines a new version of if:
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
Eva demonstrates the program for Alyssa:
(new-if (= 2 3) 0 5)
5
(new-if (= 1 1) 0 5)
0
Delighted, Alyssa uses new-if to rewrite the square-root program:
(define (sqrt-iter guess x)
(new-if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))
What happens when Alyssa attempts to use this to compute square roots? Explain.
我们的语言 scheme 使用的是 applicative-order evaluation,也就是对于一个过程,我们要把过程的所有参数全部计算完毕之后,将计算的结果传递到过程中。
对于 (if test then else) 中 if 这个“过程”而言,我们当然不能将 if 的所有参数全部计算出来再传递给 if 去判断,然后再决定返回 then 的值还是 else 的值。我们需要的是,先计算 test,then 和 else 部分都不执行,然后再去选择执行后续的操作。
这就是 if 作为一个特殊过程,和例子中的 new-if 的区别。
new-if 写到了 sqrt-iter 中后,每次碰到 new-if 都不是先去计算 goog-enough? 然后决定要不要返回 guess,它会一直去调用作为 new-if 参数的 sqrt-iter,进入死循环。(事实上,scheme 的参数的执行顺序是从右到左,goog-enough? 是完全没有执行。)