This page has been validated.
Steele and Sussman March 10, 1976 4 LAMBDA: The Ultimate Imperative

(DEFINE FACT
   (LAMBDA (M)
       (LABELS ((FACT1 (LAMBDA (M ANS)
                           (IF (= M 0) ANS
                                   (FACT1 (- M 1)
                                          (* M ANS))))))
                (FACT1 N 1))))

From this we can infer a general way to express iterations in SCHEME in a manner isomorphic to the MacLISP DO. The expansion of the general DO loop

(DO ((<var1> <init1> <step1>)
     (<var2> <init2> <step2>)
     . . .
     (<varn> <initn> <stepn>))
    (<pred> <value>)
    <body>)

is this:

(LABELS ((DOLOOP
          (LAMBDA (DUMMY <var1> <var2> ... <varn>)
              (IF <pred> <value>
                  (DOLOOP <body> <step1> <step2> ... <stepn>)))))
        (DOLOOP NIL <init1> <init2> ... <initn>))

The identifiers DOLOOP and DUMMY are chosen so as not to conflict with any other identifiers in the program.

Note that, unlike most implementations of DO, there are no side effects in the steppings of the iteration variables. DO loops are usually modelled using assignment statements. For example:

for x := a step b until c do <statement>;

can be modelled as follows: [Naur 63]

begin
    x := a;
 L: if (x-c)*sign(b) > 0 then go to Endloop;
    <statement>;
    x := x+b;
    go to L;
 Endloop:
end;

Later we will see how such assignment statements can in general be modelled without using side effects.