Next: Special-Clause Operators, Up: Iteration Forms [Contents][Index]
Iteration macros are global macros acting as the entry points of this package.
:result
expression…)]) ([for-clause…]) [body…] ¶This iteration macro is the fundamental building block of other iteration macros. bodys are first transformed according to the following rules and appended to for-clauses preserving their order:
:do
clause
unless it is already a special clause;
for-clauses are then processed in order. Multiple adjacent
iteration clauses are treated as a group, and special clauses serve to
separate the groups of iteration clauses. A group of iteration clauses
expands to a while
loop wrapping the body expanded so far, and a
special clause expands according to its idiosyncratic rules, presumably
wrapping the body expanded so far. A group of iteration clauses or a
special clause to the left of another group of iteration clauses or
special clause nests the latter. The last form is a multiple-value form
that produces as many values as there are bindings. It is an
error for the multiple-value form to produce not as many values as there
are bindings.
After for-clauses are processed, expressions are appended to
the body, and bindings are bound by a let
form wrapping the
body. Given that binding has either the form
(identifier [expression])
or
identifier, expression defaults to nil
when there is
no identifier, identifier when there is one, (cons
identifier…)
when there are two, and (list
identifier…)
when there are three or more.
An iteration clause has the form (pattern
sequence-form)
where pattern is a pcase
pattern and
sequence-form is either (head
[subform…])
or datum. Alternatively, it
has the form (sequence-form)
, which is first transformed to
the former with a generated identifier as pattern. It is then
iteratively expanded as follows:
:do-in
form, terminate the
expansion;
(pattern (head datum))
where head is the
corresponding sequence constructor;
(pattern (base [subform…]))
;
(pattern (for-in-iterator (for-generator
datum)))
.
For each identifier and each value produced by the
multiple-value form, identifier is first bound to the value of
expression or nil
when there is no expression and
later updated to value after each iteration12.
:result
expression…)]) ([for-clause…]) [body…] ¶This iteration macro is the implicitly nesting version of
for-fold
, such that every iteration clause is a group in its own.
This is achieved by separating each pair of adjacent iteration clauses
with a vacuous special clause such as (:do)
.
Below, for-clause*s are for-clauses including the
transformed bodys but excluding the multiple-value form, and
value* is the multiple-value form where each tail form
(:values expression)
is replaced by expression,
implying that it is an error for the multiple-value form to produce not
exactly one value.
:result
expression…)]) ([for-clause…]) [body…] ¶This iteration macro is the reverse of for-fold
. The sequences
are still iterated in the same order, but the bindings are updated in
reverse order. As such, it uses space proportional to the number of
iterations. It is equivalent to the following form (see (elisp)Calling
Functions) where next is a generated identifier,
updates update bindings to the produced values, and
expression is potentially the default expression:
(let ([binding…]) (funcall (for-fold ((next #'ignore)) ([for-clause*…] (:let (next next)) (lambda () [update…] (funcall next))))) expression…)
It is an error for the expanded form to execute under dynamic binding (see (elisp)Variable Scoping).
:result
expression…)]) ([for-clause…]) [body…] ¶This iteration macro is the implicitly nesting version of
for-foldr
.
This iteration macro performs side effects and produces nil
as
the value. It is equivalent to the following form:
(for-fold () ([for-clause…]) [body…] (:values))
This iteration macro is the implicitly nesting version of for-do
.
This iteration macro accumulates the values into a fresh13 list and returns the list. It is equivalent to the following form where list is a generated identifier:
(for-fold ((list '()) (:result (nreverse list))) ([for-clause*…] (cons value* list)))
This iteration macro is the implicitly nesting version of
for-list
.
This iteration macro returns an iterator of the produced values. It is equivalent to the following form:
(iter-make (for-do ([for-clause*…] (:do (iter-yield value*)))))
It is an error for the expanded form to execute under dynamic binding.
This iteration macro is the implicitly nesting version of
for-iter
.
:result
expression…)]) ([for-clause…]) [body…] ¶This iteration macro accumulates the values into fresh lists and
sequentially evaluates expressions with identifiers bound to
the lists. It is like for-fold
, except:
(identifier '())
as
binding, and expressions are wrapped in a let
form
with each identifier bound to (nreverse identifier)
;
(cons expression identifier)
. It is an error for the
multiple-value form to produce not as many values as there are
identifiers.
The values of identifiers during the iteration are unspecified.
:result
expression…)]) ([for-clause…]) [body…] ¶This iteration macro is the implicitly nesting version of
for-lists
.
:length
length [:init
init]] [body…] ¶When neither length nor init is present, this iteration
macro is equivalent to the following form (see (elisp)Vector
Functions), such that it coerces14 the list returned by for-list
to vector:
(vconcat (for-list ([for-clause…]) [body…]))
Otherwise, this iteration macro accumulates the values into a fresh
vector of length length with each element being init where
init defaults to 0
when omitted. In such case, it is
equivalent to the following form (see (elisp)Setting Generalized
Variables) where vector and index are generated
identifiers provided that length and init are evaluated
exactly once in the apparent evaluation order:
(let ((vector (make-vector length init))) (unless (zerop length) (for-fold ((index 0)) ([for-clause*…] (:do (setf (aref vector index) value*)) (:let (index (1+ index))) (:break (= index length)) index))) vector)
:length
length [:init
init]] [body…] ¶This iteration macro is the implicitly nesting version of
for-vector
.
:length
length [:init
init [:multibyte
multibyte]]] [body…] ¶When neither length, init, nor multibyte is present,
this iteration macro is equivalent to the following form
(see (elisp)Creating Strings), such that it coerces the list
returned by for-list
to string:
(concat (for-list ([for-clause…]) [body…]))
Otherwise, this iteration macro accumulates the values into a fresh
string of length length with each element being init where
init defaults to ?\0
(see (elisp)General Escape
Syntax) when omitted. The string is always a multibyte string
(see (elisp)Non-ASCII Characters) when multibyte is true. In
such case, it is equivalent to the following form where string and
index are generated identifiers provided that length,
init, and multibyte are evaluated exactly once in the
apparent evaluation order:
(let ((string (make-string length init multibyte))) (unless (zerop length) (for-fold ((index 0)) ([for-clause*…] (:do (setf (aref string index) value*)) (:let (index (1+ index))) (:break (= index length)) index))) string)
:length
length [:init
init [:multibyte
multibyte]]] [body…] ¶This iteration macro is the implicitly nesting version of
for-string
.
This iteration macro performs and
(see (elisp)Combining
Conditions) on the values. It is equivalent to the following
form where value is a generated identifier:
(for-fold ((value t)) ([for-clause*…] (:let (value value*)) (:final (not value)) value))
This iteration macro is the implicitly nesting version of
for-and
.
This iteration macro performs or
on the values. It is equivalent
to the following form where value is a generated identifier:
(for-fold ((value nil)) ([for-clause*…] (:let (value value*)) (:final value) value))
This iteration macro is the implicitly nesting version of for-or
.
This iteration macro accumulates the values into a sum. It is equivalent to the following form where sum is a generated identifier:
(for-fold ((sum 0)) ([for-clause*…] (+ value* sum)))
This iteration macro is the implicitly nesting version of
for-sum
.
This iteration macro accumulates the values into a product. It is equivalent to the following form where product is a generated identifier:
(for-fold ((product 0)) ([for-clause*…] (* value* product)))
This iteration macro is the implicitly nesting version of
for-product
.
This iteration macro returns the first value or nil
if the
iteration never begins. It is equivalent to the following form where
value is a generated identifier:
(for-fold ((value nil)) ((:final) [for-clause…]) [body…])
This iteration macro is the implicitly nesting version of
for-first
.
This iteration macro returns the last value or nil
if the
iteration never begins. It is equivalent to the following form where
value is a generated identifier:
(for-fold ((value nil)) ([for-clause…]) [body…])
This iteration macro is the implicitly nesting version of
for-last
.
This iteration macro performs max
(see (elisp)Comparison of
Numbers) on the values. It is equivalent to the following form
where max is a generated identifier:
(for-fold ((max -1.0e+INF)) ([for-clause*…] (max value* max)))
This iteration macro is the implicitly nesting version of
for-max
.
This iteration macro performs min
on the values. It is
equivalent to the following form where min is a generated
identifier:
(for-fold ((min 1.0e+INF)) ([for-clause*…] (min value* min)))
Note that the
behavior of bindings is subtlety different from that of
named-let
. In named-let
, each application of the
self-recursive function creates new bindings, just as normal function
application does. In contrast, for-fold
always retains the same
bindings.
Following Common Lisp, a fresh object is newly allocated.
Following Common Lisp, coerce means to non-destructively convert an object to another type.
Next: Special-Clause Operators, Up: Iteration Forms [Contents][Index]