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.