Next: Delayed evaluation, Previous: Sequencing, Up: Derived expression types [Index]
(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
“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))
Next: Delayed evaluation, Previous: Sequencing, Up: Derived expression types [Index]