From: Ted Sandler
Subject: an SICP puzzler ("new-if")
Date: 
Message-ID: <3B259263.435CC575@worldnet.att.net>
I've just started reading SICP wherein Abelson/Sussman pose the
question, "Why is the 'if' special form necessesary when one could
define 'if' in terms of cond?"  I've presented their scheme "define" as
a lisp "defun" below:

  (defun new-if (predicate then-clause else-clause)
         (cond (predicate then-clause)
               (t else-clause)))

They go on to point out that the "new-if" construction works fine in
simple constructs like:

  (defun my-max (x y)
    (new-if (> x y)
            x
            y))
          	
But it fails in cases like this:

  (defun fact (x)
    (new-if (zerop x)
            1
            (* x (fact (- x 1)))))

and results in infinite recursion.

My question is why the heck does this ···········@!

My guess is that the "pred" argument is acting like a lexical closure
and that "x" is being captured.  Therefore, the predicate is testing
(zerop x) as opposed to (zerop (- x 1)).  But this is just a guess.  I'd
really love a solid answer.

Thanks,
- Ted

-- 
··········@att.net

From: Sunil Mishra
Subject: Re: an SICP puzzler ("new-if")
Date: 
Message-ID: <3B259958.4030301@notmyemail.com>
Ted Sandler wrote:

> I've just started reading SICP wherein Abelson/Sussman pose the
> question, "Why is the 'if' special form necessesary when one could
> define 'if' in terms of cond?"  I've presented their scheme "define" as
> a lisp "defun" below:
> 
>   (defun new-if (predicate then-clause else-clause)
>          (cond (predicate then-clause)
>                (t else-clause)))
> 
> They go on to point out that the "new-if" construction works fine in
> simple constructs like:
> 
>   (defun my-max (x y)
>     (new-if (> x y)
>             x
>             y))
>           	
> But it fails in cases like this:
> 
>   (defun fact (x)
>     (new-if (zerop x)
>             1
>             (* x (fact (- x 1)))))
> 
> and results in infinite recursion.
> 
> My question is why the heck does this ···········@!
> 
> My guess is that the "pred" argument is acting like a lexical closure
> and that "x" is being captured.  Therefore, the predicate is testing
> (zerop x) as opposed to (zerop (- x 1)).  But this is just a guess.  I'd
> really love a solid answer.
> 
> Thanks,
> - Ted
> 
> 

It has to do with the order of argument evaluation. A special form is 
special because it can control when its arguments are evaluated. An 
ordinary function call on the other hand must have its arguments 
evaluated before it is invoked. Your NEW-IF is a function, and its 
arguments must be completely evaluated before it is invoked. In the 
factorial function, you simultaneously evaluate the condition, the 
then-clause and the else-clause. In the evaluation of the else-clause 
you re-invoke your factorial function, without first having the 
opportunity to test the return value of the condition! The special form 
IF on the other hand will evaluate only one of the then-clause or 
else-clause, as dictated by the value of the condition. So it will get 
the opportunity to halt its computation at the right time.

Hope that helps.

Sunil
From: Bulent Murtezaoglu
Subject: Re: an SICP puzzler ("new-if")
Date: 
Message-ID: <87g0d6gwwj.fsf@nkapi.internal>
>>>>> "TS" == Ted Sandler <··········@worldnet.att.net> writes:

    TS> I've just started reading SICP wherein Abelson/Sussman pose
    TS> the question, "Why is the 'if' special form necessesary when
    TS> one could define 'if' in terms of cond?"  I've presented their
    TS> scheme "define" as a lisp "defun" below:

    TS>   (defun new-if (predicate then-clause else-clause) (cond
    TS> (predicate then-clause) (t else-clause)))  

This should be covered in the section preceding that question.
I mean the bit about what happens to function arguments when the
function is called.

    TS> [...] My question is why the heck does this ···········@!

[I deleted your theory]  Trying (new-if (= x 0) x (1/x))  might help
you better than the factorial example to see why. 

cheers,

BM
From: Bulent Murtezaoglu
Subject: Re: an SICP puzzler ("new-if")
Date: 
Message-ID: <87d78agw2g.fsf@nkapi.internal>
>>>>> "TS" == Ted Sandler <··········@worldnet.att.net> writes:

    TS> I've just started reading SICP wherein Abelson/Sussman pose
    TS> the question, "Why is the 'if' special form necessesary when
    TS> one could define 'if' in terms of cond?"  I've presented their
    TS> scheme "define" as a lisp "defun" below:

    TS>   (defun new-if (predicate then-clause else-clause) (cond
    TS> (predicate then-clause) (t else-clause)))  

This should be covered in the section preceding that question.
I mean the bit about what happens to function arguments when the
function is called.

    TS> [...] My question is why the heck does this ···········@!

[I deleted your theory]  Trying (new-if (= x 0) x (/ 1 x))  with x bound 
to 0 and 1 might help you better than the factorial example to see why. 

cheers,

BM