Page:AIM-353.djvu/5



The general form of a SCHEME  is:

 (DO ( . . .    (&lt;varn>  ))        )

The semantics of this are that the variables are bound and initialized to the values of the  expressions, which must all be evaluated in the environment outside the  ; then the predicate   is evaluated in the new environment, and if , the   is evaluated and returned. Otherwise the  is evaluated, then each of the steppers   is evaluated in the current environment, all the variables made to have the results as their values, the predicate evaluated again, and so on.

Using  loops in both ALGOL and SCHEME, we may express   by means of iteration.

 integer procedure fact(n); value n; integer n; begin integer m, ans; ans := 1; for m := n step -1 until 0 do ans := m*ans; fact := ans; end;

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

Note that the SCHEME  loop in   has no body — the stepping functions do all the work. The ALGOL  loop has an assignment in its body; because an ALGOL   loop can step only one variable, we need the assignment to step the thethe [sic] variable "manually".

In reality the SCHEME  construct is not a primitive; it is a macro which expands into a function which performs the iteration by tail-recursion. Consider the following definition of  in SCHEME. Although it appears to be recursive, since it "calls itself", it is entirely equivalent to the  loop given above, for it is the code that the   macro expands into! It captures the essence of our intuitive notion or iteration, because execution of this program will not produce internal structures (e.g. stacks or variable bindings) which increase in size with the number of iteration steps.