SICP-solution-1.6

Posted by Jerry Wang on 2016-08-25

这个问题问:如果用new-if替换if的话,原来的计算平方根程序会发生什么情况?
我刚开始没想明白,后来看网上的提示忽然懂了。lisp是应用序求值语言,比如函数调用的过程中,参数是表达式的形式,则必须把表达式的值计算出来。这样是为了防止重复计算。但有一种情况比较特殊:if。看下面的程序:

(define (p) (p))

如果调用p这个函数的话,则会永远递归下去。

(if (= 9 9) 0 (p))

但if比较特殊,不需要把(p)的值也eval出来。上面这个语句会输出0。由于9==9,所以直接输出0,没必要再计算p的返回值了。(符合scheme不重复计算的性格)
如果这个时候自作聪明,自己想用cond实现if:

(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause) (else else-clause)))

我们试着调用new-if看看

(new-if (= 9 9) 0 (p))

程序会一直递归下去,原因是new-if会把0和p的值都计算出来再进行判断!
这个时候你能明白为什么平方根也计算不出来了吧?
因为调用new-if的时候,需要把后一个分支的返回值算出来,也就是说每次递归调用new-if,都应该按照应用序原则,把(sqrt-iter (improve guess x) x算出来,这样一直递归调用下去。。。