Racket Lisp:new-if和if之间的比较

时间:2012-09-17 03:51:50

标签: lisp scheme racket sicp

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

(define (improve guess x)
  (average guess(/ x guess)))

(define (average x y)
  (/ (+ x y) 2))

(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.0001))

(define (square x)
  (* x x))

(define (sqrt-g x)
  (sqrt-iter 1.0 x))

这是sqrt的一个程序。问题是当你尝试使用new-if来替换if时使用new-if。

会发生什么
(define (sqrt-iter guess x)
    (if (good-enough? guess x)
        guess
        (sqrt-iter(improve guess x)
                  x)))

这是新的

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

我的观点是两个程序的结果是一样的。因为new-if和if可以产生相同的结果。

然而,新的 - 如果证明是错误的,因为当我尝试时它是一个死圈。

那么,为什么?

3 个答案:

答案 0 :(得分:8)

new-if是一个功能。 调用函数之前,计算函数的所有参数。但是sqrt-iter是一个递归函数,当参数已经足够好时,你需要避免进行递归调用。

内置if是语法,仅根据条件的值计算then-branch或else-branch。

您可以使用宏来编写new-if

答案 1 :(得分:3)

这是演示代数步进器的完美示例! 在代数步进器中,您可以看到计算过程与您的期望有何不同。在这里,您必须注意评估的差异,例如(new-if 1 2 3)和(如果1 2 3)。

如果您之前没有尝试过代数步进器,请参阅此answer以查看其外观。

答案 2 :(得分:0)

由于球拍是一个可应用的程序,因此new-if的第三个参数为(sqrt-iter(improve guess x) x))。由于sqrt-iter是递归的,因此第三个参数永远不会分配值。因此,您永远不会进入new-if的过程来评估函数。