Next: Sequence Forms, Up: Basic Concepts [Contents][Index]
The expansion of an iteration form is driven by a series of for
clauses, classified into iteration clauses and special
clauses. Iteration clauses decide the shapes of the expanded forms,
and special clauses wrap the partially expanded forms in some ways. For
example, an iteration clause (item '(a 2 "3"))
decides that
item
is bound to each car
of the literal list
(see (elisp)Quoting) sequence (a 2 "3")
and that the
iteration is stopped when it reaches the terminating empty list
(see (elisp)Box Diagrams)6. A special clause (:if (numberp
item))
following the iteration clause decides that the partially
expanded form is skipped unless item
is numberp
(see (elisp)Predicates on Numbers).
sum
is only updated when item
is numberp
:
(for-fold ((sum 0)) ((item '(a 2 "3")) (:if (numberp item)) (+ item sum))) ⇒ 2
An equivalent named-let
form:
(let ((sum 0)) (named-let loop ((sum sum) (tail '(a 2 "3"))) (if (null tail) sum (let ((item (car tail))) (loop (if (numberp item) (+ item sum) sum) (cdr tail)))))) ⇒ 2
Adjacent iteration clauses are considered parallel and thus iterated at the same time. When one of them ends, the iteration ends. This gives rise to the usefulness of infinite sequences.
(for-in-infinite-range [start
[step]])
7 is an infinite
sequence:
(for-list ((natural (for-in-infinite-range 0)) (item '(a b c)) (cons natural item))) ⇒ ((0 . a) (1 . b) (2 . c))
As a consequence, special clauses also serve the purpose of delimiting iteration clauses into groups. A group of iteration clauses preceded by another group is effectively nested. Because the nesting behavior is so commonly desired, implicitly nesting variants of the iteration forms are provided. They transform the for clauses by separating each pair of adjacent iteration clauses with a vacuous special clause.
(item2 '(2 3 4))
nested by (item1 '(1 2))
due to the
presence of (:do)
:
(for-list ((item1 '(1 2)) (:do) (item2 '(2 3 4)) (cons item1 item2))) ⇒ ((1 . 2) (1 . 3) (1 . 4) (2 . 2) (2 . 3) (2 . 4))
An equivalent for-list*
form:
(for-list* ((item1 '(1 2)) (item2 '(2 3 4)) (cons item1 item2))) ⇒ ((1 . 2) (1 . 3) (1 . 4) (2 . 2) (2 . 3) (2 . 4))
An iteration clause normally has the form (pattern
sequence)
where pattern is a pcase
pattern and
sequence is a sequence form. Alternatively, it can have the form
(sequence)
, in which case it is transformed to
(identifier sequence)
with a generated
identifier8 (see (elisp)Creating Symbols) as identifier. A
special clause has the form (keyword . subforms)
where keyword is one of the keywords (see (elisp)Constant
Variables) accepted by the grammar and the form of
subforms is decided by keyword.
Following R5RS (Revised5 Report on the Algorithmic Language Scheme), an error does not specify whether or when the error is detected or reported.
In this manual, unless otherwise
specified, an object is a list if and only if it is a proper list.
Following
Common Lisp and Emacs Lisp (see (elisp)Cons Cells), a proper
list is either the empty list or a list terminated by the empty list.
It is an error5 for it to be any other structure produced by
cons
(see (elisp)Building Lists), that is, a circular
list or a dotted list.
In this manual, a metavariable is typeset as ‘metavariable’, an optional form as ‘[optional-form]’, and a form repeated once or more as ‘repeated-form…’. This is the same as the Emacs Lisp Manual (see (elisp)A Sample Function Description) modulo the ‘repeated-form…’ convention.
In R6RS (Revised6 Report on the Algorithmic Language Scheme), an identifier is roughly a syntax object of non-constant symbol. Emacs Lisp does not have the concept of syntax object. Nonetheless, this manual follows such usage of the terminology.
Next: Sequence Forms, Up: Basic Concepts [Contents][Index]