Page:AIM-353.djvu/11



 (DEFINE FACT       (LAMBDA (N) (DO ((M N (- M 1)) (ANS 1 (* M ANS)))                ((= M 0) ANS))))

would expand into:

 (DEFINE FACT       (LAMBDA (N) (PROG (M ANS)                     (SSETQ M    N                             ANS  1)                 LP   (IF (= M 0) (RETURN ANS))                       (SSETQ M    (- M 1) ANS (* M ANS))                      (GO LP))))

where  is a simultaneous multiple assignment operator. ( is not a SCHEME (or LISP) primitive. It can be defined in terms of a single assignment operator, but we are more interested here in   than in simultaneous assignment. The  's will all be removed anyway and modelled by lambda binding.) We can apply the same technique we used before to eliminate GO TO statements and assignments from compound statements:

 (DEFINE FACT       (LAMBDA (N) (LABELS ((L1 (LAMBDA (M ANS) (LP N 1))) (LP (LAMBDA (M ANS) (IF (= M 0) (RETURN ANS)                                        (L2 M ANS)))) (L2 (LAMBDA (M ANS) (LP (- M 1) (* N ANS)))))                       (L1 NIL NIL))))

We still haven't done anything about. Let's see...

the value of  is the value of

which is the value of

which is the value of

which is the value of  Notice that if   were the identity function , we would get the right answer. This is in fact a general truth: if we just replace a call to  with its argument, then our old transformation on compound statements extends to general compound expressions, i.e..