The simplest iteration construct in LISP is loop
: a loop
construct
repeatedly executes its body until it hits a return
special form. For
example,
> (setq a 4)
4
> (loop
(setq a (+ a 1))
(when (> a 7) (return a)))
8
> (loop
(setq a (- a 1))
(when (< a 3) (return)))
NIL
The next simplest is dolist
: dolist
binds a variable to the
elements of
a list in order and stops when it hits the end of the list.
> (dolist (x '(a b c)) (print x))
A
B
C
NIL
Dolist
always returns nil
. Note that the value of x
in the above
example was never nil
: the NIL
below the C was the value
that dolist
returned, printed by the read-eval-print loop.
The most complicated iteration primitive is called do
. A do
statement
looks like this:
> (do ((x 1 (+ x 1))
(y 1 (* y 2)))
((> x 5) y)
(print y)
(print 'working)
)
1
WORKING
2
WORKING
4
WORKING
8
WORKING
16
WORKING
32
The first part of a do
specifies what variables to bind, what their
initial values are, and how to update them. The second part specifies a
termination condition and a return value. The last part is the body. A
do form binds its variables to their initial values like a let
, then
checks the termination condition. As long as the condition is false, it
executes the body repeatedly; when the condition becomes true, it
returns the value of the return-value form.
The do
* form is to do
as let
* is to let
.