**Exercise 1.6:** 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.

`sqrt-iter`

implemented with `new-if`

will create an infinite loop, this is because scheme uses
Applicative Order Evaluation rule by default. In a regular `if`

statement all expressions get
evaluated in order of need not at the same time. This difference in the order of evaluation is
what makes an passing arguments to an if statement different than passing arguments to functions
such as `new-if`

in Applicative Order systems. The way sqrt-iter is implemented using `new-if`

implies the following evaluation rules: `good-enough?`

returns true or false (doesn’t matter
which), “guess” is already a number and hence in the simplest form it doesn’t get evaluated
any further. The infinite recursion occurs at `sqrt-iter`

call because it will get evaluated
no matter what `good-enough?`

does since `new-if`

is just a regular function and under AOE
all arguments must be evaluated fully before passed to a function.

Another example of the difference between argument evaluation:

```
> (if (> 1 0) 1 (/ 1 0)))
1
(new-if (> 1 0) 1 (/ 1 0)))
*** ERROR -- Divide by zero (/ 1 0)
```

Clearly a standard if doesn’t evaluate the last argument until it must. It will only evaluate it
in the case where the predicate `(> 1 0)`

will evaluate to false, which will never happen. On
the other hand `new-if`

evaluates everything right away, the interpreter tries to expand and
pass the following `(new-if #t 1 *ERROR!*)`

It’s interesting that to make `new-if`

behave correctly only requires to change the evaluation
strategy to Normal Order Evaluation and the `sqrt-iter`

code will work. I wouldn’t want to
trace the NOE version of `sqrt-iter`

because `improve`

functions don’t get evaluated and
just get passed along with every recursive call which makes them, a nightmare to untangle on paper.