2009-07-23 51 views
49

我刚开始工作通过SICP(我自己;这不是一个班级),并且我一直在努力练习1.6几天,我似乎无法弄清楚。在cond而言这是一个地方贾静雯重新定义if,像这样:SICP练习1.6的解释是什么?

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

她成功地测试它在一些简单的情况下,然后使用它来重新写的平方根程序(这只是工作细跟if):

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

那么接下来的问题问:“当阿丽莎试图以此来计算平方根说明会发生什么?”。 [如果有必要,我很高兴能重现其他程序(good-enough?improve等),只是让我知道。]

现在,我知道会发生什么:它永远不会返回一个值,这意味着程序无限递归。我无法解释为什么会发生这种情况。无论ifnew-if之间存在什么细微差别,都无法避免。任何和所有的帮助非常感谢。

+1

“递归”的动词形式是“recurse”,所以它“递归”。 – 2009-07-23 11:57:29

+0

你的问题标题是错误的:你指的是练习1.6,而不是1.4。 – systemovich 2010-12-12 15:24:23

回答

62

new-if是一个函数。当一个函数被调用时,Scheme对参数列表做的第一件事是什么?它评估全部的论点。

20

首先你必须understand the difference适用订单评估和正常订单之间。 Lisp的应用性使用顺序,但条件表达式求值不象正常功能(sicp chapter 1.1.6):

(if <predicate> <consequent> <alternative>) 

为了评估一个if语句,解释器通过评估表达的<predicate>部分开始。如果<predicate>的计算结果为真值,则解释程序将评估<consequent>并返回其值。否则,它会评估<alternative>并返回其值。

28

new-if是一个过程,并计划使用应用性,为了评价(1.1.5),所以即使之前new-if被实际执行,它必须首先评估所有的参数,这是guess(sqrt-iter (improve guess x) x)。你可以看到后一个参数是一个递归,它调用了一个新的new-if过程,这是发生无限循环的方式。

普通的if不需要首先评估它的参数,只是一路走来,这是ifnew-if之间的区别。 :)