Skip to content

Latest commit

 

History

History
59 lines (42 loc) · 1.56 KB

1.6.md

File metadata and controls

59 lines (42 loc) · 1.56 KB

1.6

Question

Alyssa P. Hacker doesn't see why if needs to be provided as a special form. "Why can't I just define it as an ordinary procedure in terms of cond?" she asks. Alyssa's friend Eva Lu Ator claims this can indeed be done, and she defines a new version of if:

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

Eva demonstrates the program for Alyssa:

(new-if (= 2 3) 0 5)
5

(new-if (= 1 1) 0 5)
0

Delighted, Alyssa uses new-if to rewrite the square-root program:

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

What happens when Alyssa attempts to use this to compute square roots? Explain.

Answer

(define (good-enough? guess x)
  (< (abs (- (* guess guess) x)) 0.001))

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

(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause))) ; <-- Eager evalution

(define (new-if-sqrt-iter guess x)
  (new-if (good-enough? guess x)
          guess 
          (new-if-sqrt-iter (improve guess x) x))) ; <-- Infinite recursion

(new-if-sqrt-iter 1.0 2) ; Non-halting
(new-if (= 1 1) (+ 1 1) (/ 1 0)) ; Fails

The if operator is normal-order, only evaluating the branch chosen by the predicate.

The new-if procedure is applicative-order, causing infinite recursion in the evaluation of else-clause before the predicate can direct the program flow.