This section describes the remaining loop clauses.
(cl-loop with x = 17 do ...) (let ((x 17)) (cl-loop do ...)) (cl-loop for x = 17 then x do ...)
Naturally, the variable var might be used for some purpose in the rest of the loop. For example:
(cl-loop for x in my-list with res = nil do (push x res) finally return res)
This loop inserts the elements of
my-list at the front of
a new list being accumulated in
res, then returns the
res at the end of the loop. The effect is similar
to that of a
collect clause, but the list gets reversed
by virtue of the fact that elements are being pushed onto the
res rather than the end.
If you omit the
= term, the variable is initialized to
nil. (Thus the ‘= nil’ in the above example is
Bindings made by
with are sequential by default, as if
let*. Just like
can be linked with
and to cause the bindings to be made by
unlessclause. Several clauses may be linked by separating them with
and. These clauses may be followed by
elseand a clause or clauses to execute if the condition was false. The whole construct may optionally be followed by the word
end(which may be used to disambiguate an
andin a nested
The actual non-
nil value of the condition form is available
by the name
it in the “then” part. For example:
(setq funny-numbers '(6 13 -1)) ⇒ (6 13 -1) (cl-loop for x below 10 if (cl-oddp x) collect x into odds and if (memq x funny-numbers) return (cdr it) end else collect x into evens finally return (vector odds evens)) ⇒ [(1 3 5 7 9) (0 2 4 6 8)] (setq funny-numbers '(6 7 13 -1)) ⇒ (6 7 13 -1) (cl-loop <same thing again>) ⇒ (13 -1)
Note the use of
and to put two clauses into the “then”
part, one of which is itself an
if clause. Note also that
end, while normally optional, was necessary here to make
it clear that the
else refers to the outermost
clause. In the first case, the loop returns a vector of lists
of the odd and even values of x. In the second case, the
odd number 7 is one of the
funny-numbers so the loop
returns early; the actual returned value is based on the result
unlessclause is just like
ifexcept that the sense of the condition is reversed.
nilto the implicit block surrounding the loop. The name is the symbol to be used as the block name.
withhave been bound to their initial values).
initiallyclauses can appear anywhere; if there are several, they are executed in the order they appear in the loop. The keyword
finallyclauses may appear anywhere in the loop construct, but they are executed (in the specified order) at the beginning or end, respectively, of the loop.
return, the loop will simply return
nil.) Variables bound by
intowill still contain their final values when form is executed.
domay be followed by any number of Lisp expressions which are executed as an implicit
prognin the body of the loop. Many of the examples in this section illustrate the use of
finallyclauses, if any, are not executed. Of course,
returnis generally used inside an
unless, as its use in a top-level loop clause would mean the loop would never get to “loop” more than once.
The clause ‘return form’ is equivalent to
‘do (cl-return form)’ (or
cl-return-from if the loop
was named). The
return clause is implemented a bit more
While there is no high-level way to add user extensions to
this package does offer two properties called
cl-loop-for-handler which are functions to be called when a
given symbol is encountered as a top-level loop clause or
clause, respectively. Consult the source code in file
cl-macs.el for details.
cl-loop macro is compatible with that of Common
Lisp, except that a few features are not implemented:
and data-type specifiers. Naturally, the
for clauses that
iterate over keymaps, overlays, intervals, frames, windows, and
buffers are Emacs-specific extensions.