<< Previous exercise (1.45) | Index | Next exercise (2.1) >>

 (define (close-enough? v1 v2) 
   (define tolerance 1.e-6) 
   (< (/ (abs (- v1 v2)) v2)  tolerance)) 
 (define (iterative-improve improve close-enough?) 
   (lambda (x) 
     (let ((xim (improve x))) 
       (if (close-enough? x xim) 
         ((iterative-improve improve close-enough?) xim)) 
 ; (a) rewrite sqrt using iterative-improve 
 (define (sqrt x) 
     (lambda (y) 
       (/ (+ (/ x y) y) 2)) 
     close-enough?) 1.0)) 
 ; (b) rewrite fixed-point using iterative-improve 
 (define (fixed-point f first-guess) 
     ; improve function is nothing but the 
     ; function f whose fixed point is to be found! 
     close-enough?) first-guess)) 

I'll propose another solution, which seems more clear and according to the statement (to me), since the arguments to iterative-improve must:

  1. tell if a guess is good enough
  2. improve a guess
 (define (iterative-improve good-enough? improve) 
   (lambda (x) 
     (define (iter n) 
       (if (good-enough? n) 
           (iter (improve n)))) 
     (iter x))) 
 (define (close-enough? v1 v2) 
   (< (abs (- v1 v2)) tolerance)) 
 (define (fixed-point f first-guess) 
     (lambda (x) (close-enough? x (f x))) 
     (lambda (x) (f x))) 
 (define (sqrt x) 
     (lambda (y) 
       (< (abs (- (square y) x)) 
     (lambda (y) 
       (average y (/ x y)))) 

There is yet another solution:

  1. that gets rid of the lambda expression in iterative-improve
  2. that shows more clearly how iteration will be performed
  3. that allows the two examples to have exactly the same pattern by giving sqrt-good-enough? an extra parameter which, however, it does not use

--Rather Iffy

 (define (iterative-improve good-enuf improve-guess) 
   (define (keep-on-trying guess) 
     (let ((next (improve-guess guess))) 
       (if (good-enuf guess next) 
           guess                            ;there is a choice :guess or next 
           (keep-on-trying next)))) 
 (define (sqrt x) 
   (define (sqrt-good-enough? guess next )  ;extra arg next, not used by sqrt       
   (< (abs (- (square guess) x)) 0.001)) 
   (define (sqrt-improve-guess guess ) 
     (define (average x y) 
     (/ (+ x y) 2)) 
     (average guess (/ x guess))) 
   ((iterative-improve sqrt-good-enough? sqrt-improve-guess) 1.0)) 
 (define (fixed-point f) 
   (define (fixp-good-enough? guess next)  ;extra arg next, used by fixed-point          
     (< (abs (- guess next )) 0.00001)) 
   (define (fixp-improve-guess guess ) 
     (f guess)) 
   ((iterative-improve fixp-good-enough? fixp-improve-guess) 1.0))