exec 1.6

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


(define (good-enough guess x)
  (< (abs(- (square guess) x)) 0.001)
  )


(define (improve guess x)
  (/ (+ guess (/ x guess)) 2)
  )

// 这个题其实和1.5是一个原理,这儿的new-if是循环定义,所以采用应用序的解释器会陷入死循环;这种循环定义其实就是递归定义,只是没有机会结束递归。

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

// new-if的第二种定义,将cond换成if,效果也是一样的,这样写就更明显了,用if定义了一个新的if,就相当于是例子1.5中的(define (p) (p)),用p定义p,造成死循环;
(define (new-if predicate then-clause else-clause)
  ( if predicate then-clause
        else-clause     )
   )


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


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


这个例子给我们一个启示,不要做循环定义,循环定义不光是没有意义,还会让解释器陷入死循环。

这儿还有一个问题:cond和if功能是等价的,用cond写的程序都能用if代替,多嵌套几个if就行了;用if写的程序也能用cond代替,这个代替就更简单了,cond本来可以写多个条件,留两个就够了;那既然cond和if是等价的,为什么scheme要同时支持这两个关键字呢?

其实,只选一个的确是够了,选两个也没大碍;关键的问题是,不能像上文的例子那样,用cond定义一个if-new,也不能用if定义一个cond-new,否则程序就有死循环的可能。

哦,我们要分清楚以下两个不同的概念:

1 程序中对if的”调用“可以用cond”调用“替换,反之亦可;

2 if过程“定义本身” “不能”用cond定义;cond过程”定义本身“也“不能”用if定义;

这两个概念很容易混淆,仔细想一想。



你可能感兴趣的:(exec 1.6)