Next: Gathering Clauses, Previous: Drivers, Up: Clauses
Several clauses exist for establishing new variable bindings or for setting variables in the loop. They all support destructuring.
&optional
=
valueCauses var to be bound to value before the loop body is entered. If value is not supplied, var assumes a default binding, which will be
nil
in the absence of declarations. Also, if value is not supplied, no destructuring is performed; instead, var may be a list of symbols, all of which are given default bindings. If value is supplied, var is bound to it, with destructuring.Because
with
creates bindings whose scope includes the entireiterate
form, it is good style to put allwith
clauses at the beginning.Successive occurrences of
with
result in sequential bindings (as withlet*
). There is no way to obtain parallel bindings; see Parallel Binding and Stepping for a rationale.
On each iteration, expr is evaluated and var is set to its value.
This clause may appear to do the same thing as
for... next
. In fact, they are quite different.for... =
provides only three services: it sets up a binding for var, sets it to expr on each iteration, and makes it possible to usefor... previous
with var.for... next
provides these services in addition to the ability to turn the driver into a generator.
Before the loop begins, var is set to init-expr; on all iterations after the first it is set to then-expr. This clause must occur at top-level. init-expr will be moved outside the loop body and then-expr will be moved to the end of the loop body, so they are subject to code motion problems (see Problems with Code Movement).
This clause may appear to be similar to
for... next
, but in fact they differ significantly.for... initially... then
is typically used to give var its first value before the loop begins, and subsequent values on following iterations. This is incompatible with generators, whose first value and subsequent values must all be computed by(next
var)
. Also, the update of var infor... initially... then
does not occur at the location of the clause.Use
for... initially... then
for one-shot computations where its idiom is more convenient, but usefor... next
for extendingiterate
with new drivers (see Rolling Your Own).
The first time through the loop, var is set to first-expr; on subsequent iterations, it is set to then-expr. This differs from
for... initially
in that var is set to first-expr inside the loop body, so first-expr may depend on the results of other clauses. For instance,(iter (for num in list) (for i first num then (1+ i)) ...)will set
i
to the first element oflist
on the first iteration, whereas(iter (for num in list) (for i initially num then (1+ i)) ...)is probably erroneous;
i
will be bound tonum
's default binding (usuallynil
) for the first iteration.
Compatibility Note:loop
'sfor... =
works likeiterate
's, butloop
used the syntaxfor... =... then
to meanfor... initially... then
. It was felt that these two operations were sufficiently different to warrant different keywords.Also, the
for
in the above three clauses is misleading, since none is true driver (e.g. none has a correspondinggenerate
form).setting
would have been a better choice, butfor
was used to retain some compatibility withloop
.