(do ((⟨variable1⟩ ⟨init1⟩ ⟨step1⟩)
…)
(⟨test⟩ ⟨expression⟩ …)
⟨command⟩ …) ¶Syntax: All of ⟨init⟩, ⟨step⟩, ⟨test⟩, and ⟨command⟩ are expressions.
Semantics: A do expression is an iteration construct. It
specifies a set of variables to be bound, how they are to be initialized
at the start, and how they are to be updated on each iteration. When a
termination condition is met, the loop exits after evaluating the
⟨expression⟩s.
A do expression is evaluated as follows: The ⟨init⟩
expressions are evaluated (in some unspecified order), the
⟨variable⟩s are bound to fresh locations, the results of the
⟨init⟩ expressions are stored in the bindings of the
⟨variable⟩s, and then the iteration phase begins.
Each iteration begins by evaluating ⟨test⟩; if the result is false (see Booleans), then the ⟨command⟩ expressions are evaluated in order for effect, the ⟨step⟩ expressions are evaluated in some unspecified order, the ⟨variable⟩s are bound to fresh locations, the results of the ⟨step⟩s are stored in the bindings of the ⟨variable⟩s, and the next iteration begins.
If ⟨test⟩ evaluates to a true value, then the ⟨expression⟩s
are evaluated from left to right and the values of the last
⟨expression⟩ are returned. If no ⟨expression⟩s are present,
then the value of the do expression is unspecified.
The region of the binding of a ⟨variable⟩ consists of the entire
do expression except for the ⟨init⟩s. It is an error for a
⟨variable⟩ to appear more than once in the list of do
variables.
A ⟨step⟩ can be omitted, in which case the effect is the same as if ‘(⟨variable⟩ ⟨init⟩ ⟨variable⟩)’ had been written instead of ‘(⟨variable⟩ ⟨init⟩)’.
(do ((vec (make-vector 5)) (i 0 (+ i 1))) ((= i 5) vec) (vector-set! vec i i)) ⇒ #(0 1 2 3 4)
(let ((x '(1 3 5 7 9))) (do ((x x (cdr x)) (sum 0 (+ sum (car x)))) ((null? x) sum))) ⇒ 25
(let ⟨variable⟩ ⟨bindings⟩ ⟨body⟩) ¶Semantics: “Named let” is a variant on the syntax of
let which provides a more general looping construct than
do and can also be used to express recursion. It has the same
syntax and semantics as ordinary let except that ⟨variable⟩
is bound within ⟨body⟩ to a procedure whose formal arguments are
the bound variables and whose body is ⟨body⟩. Thus the execution
of ⟨body⟩ can be repeated by invoking the procedure named by
⟨variable⟩.
(let loop ((numbers '(3 -2 1 6 -5)) (nonneg '()) (neg '())) (cond ((null? numbers) (list nonneg neg)) ((>= (car numbers) 0) (loop (cdr numbers) (cons (car numbers) nonneg) neg)) ((< (car numbers) 0) (loop (cdr numbers) nonneg (cons (car numbers) neg))))) ⇒ ((6 1 3) (-5 -2))