Next: Iteration Clauses, Previous: Loop Examples, Up: Loop Facility
Most loops are governed by one or more for
clauses.
A for
clause simultaneously describes variables to be
bound, how those variables are to be stepped during the loop,
and usually an end condition based on those variables.
The word as
is a synonym for the word for
. This
word is followed by a variable name, then a word like from
or across
that describes the kind of iteration desired.
In Common Lisp, the phrase being the
sometimes precedes
the type of iteration; in this package both being
and
the
are optional. The word each
is a synonym
for the
, and the word that follows it may be singular
or plural: ‘for x being the elements of y’ or
‘for x being each element of y’. Which form you use
is purely a matter of style.
The variable is bound around the loop as if by let
:
(setq i 'happy) (cl-loop for i from 1 to 10 do (do-something-with i)) i ⇒ happy
for
var from
expr1 to
expr2 by
expr3for
clause creates a counting loop. Each of
the three sub-terms is optional, though there must be at least one
term so that the clause is marked as a counting clause.
The three expressions are the starting value, the ending value, and
the step value, respectively, of the variable. The loop counts
upwards by default (expr3 must be positive), from expr1
to expr2 inclusively. If you omit the from
term, the
loop counts from zero; if you omit the to
term, the loop
counts forever without stopping (unless stopped by some other
loop clause, of course); if you omit the by
term, the loop
counts in steps of one.
You can replace the word from
with upfrom
or
downfrom
to indicate the direction of the loop. Likewise,
you can replace to
with upto
or downto
.
For example, ‘for x from 5 downto 1’ executes five times
with x
taking on the integers from 5 down to 1 in turn.
Also, you can replace to
with below
or above
,
which are like upto
and downto
respectively except
that they are exclusive rather than inclusive limits:
(cl-loop for x to 10 collect x) ⇒ (0 1 2 3 4 5 6 7 8 9 10) (cl-loop for x below 10 collect x) ⇒ (0 1 2 3 4 5 6 7 8 9)
The by
value is always positive, even for downward-counting
loops. Some sort of from
value is required for downward
loops; ‘for x downto 5’ is not a valid loop clause all by
itself.
for
var in
list by
functionby
term, then function
is used to traverse the list instead of cdr
; it must be a
function taking one argument. For example:
(cl-loop for x in '(1 2 3 4 5 6) collect (* x x)) ⇒ (1 4 9 16 25 36) (cl-loop for x in '(1 2 3 4 5 6) by 'cddr collect (* x x)) ⇒ (1 9 25)
for
var on
list by
function(cl-loop for x on '(1 2 3 4) collect x) ⇒ ((1 2 3 4) (2 3 4) (3 4) (4))
for
var in-ref
list by
functionin
clause, but var becomes
a setf
-able “reference” onto the elements of the list
rather than just a temporary variable. For example,
(cl-loop for x in-ref my-list do (cl-incf x))
increments every element of my-list
in place. This clause
is an extension to standard Common Lisp.
for
var across
array(cl-loop for x across "aeiou" do (use-vowel (char-to-string x)))
for
var across-ref
arraysetf
-able
reference onto the elements; see in-ref
above.
for
var being the elements of
sequencein
or
across
. The clause may be followed by the additional term
‘using (index var2)’ to cause var2 to be bound to
the successive indices (starting at 0) of the elements.
This clause type is taken from older versions of the loop
macro,
and is not present in modern Common Lisp. The ‘using (sequence ...)’
term of the older macros is not supported.
for
var being the elements of-ref
sequencesetf
-able
reference onto the elements; see in-ref
above.
for
var being the symbols [of
obarray]
As an example,
(cl-loop for sym being the symbols when (fboundp sym) when (string-match "^map" (symbol-name sym)) collect sym)
returns a list of all the functions whose names begin with ‘map’.
The Common Lisp words external-symbols
and present-symbols
are also recognized but are equivalent to symbols
in Emacs Lisp.
Due to a minor implementation restriction, it will not work to have
more than one for
clause iterating over symbols, hash tables,
keymaps, overlays, or intervals in a given cl-loop
. Fortunately,
it would rarely if ever be useful to do so. It is valid to mix
one of these types of clauses with other clauses like for ... to
or while
.
for
var being the hash-keys of
hash-tablefor
var being the hash-values of
hash-table(cl-loop for k being the hash-keys of h using (hash-values v) do (message "key %S -> value %S" k v))
for
var being the key-codes of
keymapfor
var being the key-bindings of
keymapusing
clause can access both the codes and the bindings
together.
(cl-loop for c being the key-codes of (current-local-map) using (key-bindings b) do (message "key %S -> binding %S" c b))
for
var being the key-seqs of
keymapfor
var being the overlays [of
buffer] ...
extents
is synonymous
with overlays
). If the of
term is omitted, the current
buffer is used.
This clause also accepts optional ‘from pos’ and
‘to pos’ terms, limiting the clause to overlays which
overlap the specified region.
for
var being the intervals [of
buffer] ...
of
,
from
, to
, and property
terms, where the latter
term restricts the search to just the specified property. The
of
term may specify either a buffer or a string.
for
var being the frames
screens
is
a synonym for frames
. The frames are visited in
next-frame
order starting from selected-frame
.
for
var being the windows [of
frame]
next-window
order starting from selected-window
(or frame-selected-window
if you specify frame).
This clause treats the minibuffer window in the same way as
next-window
does. For greater flexibility, consider using
walk-windows
instead.
for
var being the buffers
for
var =
expr1 then
expr2(cl-loop for x on my-list by 'cddr do ...) (cl-loop for x = my-list then (cddr x) while x do ...)
Note that this type of for
clause does not imply any sort
of terminating condition; the above example combines it with a
while
clause to tell when to end the loop.
If you omit the then
term, expr1 is used both for
the initial setting and for successive settings:
(cl-loop for x = (random) when (> x 0) return x)
This loop keeps taking random numbers from the (random)
function until it gets a positive one, which it then returns.
If you include several for
clauses in a row, they are
treated sequentially (as if by let*
and setq
).
You can instead use the word and
to link the clauses,
in which case they are processed in parallel (as if by let
and cl-psetq
).
(cl-loop for x below 5 for y = nil then x collect (list x y)) ⇒ ((0 nil) (1 1) (2 2) (3 3) (4 4)) (cl-loop for x below 5 and y = nil then x collect (list x y)) ⇒ ((0 nil) (1 0) (2 1) (3 2) (4 3))
In the first loop, y
is set based on the value of x
that was just set by the previous clause; in the second loop,
x
and y
are set simultaneously so y
is set
based on the value of x
left over from the previous time
through the loop.
Another feature of the cl-loop
macro is destructuring,
similar in concept to the destructuring provided by defmacro
(see Argument Lists).
The var part of any for
clause can be given as a list
of variables instead of a single variable. The values produced
during loop execution must be lists; the values in the lists are
stored in the corresponding variables.
(cl-loop for (x y) in '((2 3) (4 5) (6 7)) collect (+ x y)) ⇒ (5 9 13)
In loop destructuring, if there are more values than variables
the trailing values are ignored, and if there are more variables
than values the trailing variables get the value nil
.
If nil
is used as a variable name, the corresponding
values are ignored. Destructuring may be nested, and dotted
lists of variables like (x . y)
are allowed, so for example
to process an alist
(cl-loop for (key . value) in '((a . 1) (b . 2)) collect value) ⇒ (1 2)