<< 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) xim ((iterative-improve improve close-enough?) xim)) ))) ; (a) rewrite sqrt using iterative-improve (define (sqrt x) ((iterative-improve (lambda (y) (/ (+ (/ x y) y) 2)) close-enough?) 1.0)) ; (b) rewrite fixed-point using iterative-improve (define (fixed-point f first-guess) ((iterative-improve ; improve function is nothing but the ; function f whose fixed point is to be found! f 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:

- tell if
*a guess*is**good enough** - improve a guess

(define (iterative-improve good-enough? improve) (lambda (x) (define (iter n) (if (good-enough? n) n (iter (improve n)))) (iter x))) (define (close-enough? v1 v2) (< (abs (- v1 v2)) tolerance)) (define (fixed-point f first-guess) ((iterative-improve (lambda (x) (close-enough? x (f x))) (lambda (x) (f x))) first-guess)) (define (sqrt x) ((iterative-improve (lambda (y) (< (abs (- (square y) x)) 0.0001)) (lambda (y) (average y (/ x y)))) 1.0))

There is yet another solution:

- that gets rid of the lambda expression in iterative-improve
- that shows more clearly how iteration will be performed
- 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)))) keep-on-trying) ;; (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))