Next: , Previous: , Up: Basic Concepts   [Contents][Index]


2.2 Sequence Forms

A sequence form represents an ordered collection of values, much like an iterator (see (elisp)Generators). In fact, a sequence form produces an iterator when evaluated as a function form (see (elisp)Function Forms). Nonetheless, iterators are relatively expensive since they capture the states. Rather than keeping the states in another object, a sequence form can be directly expanded in an iteration form when an expander is available.

Produce an iterator that iterates over the list and iterate over the values of it:

(let ((iterator (for-in-list '(1 2 3))))
  (for-vector ((item (for-in-iterator iterator))
               item)))
     ⇒ [1 2 3]

Directly iterate over the list:

(for-vector ((item (for-in-list '(1 2 3)))
             item))
     ⇒ [1 2 3]

For convenience, a sequence constructor can have aliases when used in iteration clauses to avoid the need of shorthands (see (elisp)Shorthands).

for-in-list and for-in-range have aliases:

(for-list ((item (in-list '(a b c)))
           (number (in-range 1 5 2))
           (cons item number)))
     ⇒ ((a . 1) (b . 3))

Dynamic dispatch is available when an arbitrary expression is used as a sequence form in iteration clauses. The expression expression is transformed to (for-in-iterator (for-generator expression)), where for-generator is a generic function (see (elisp)Generic Functions) that acts as a generator. Moreover, for-unhandled-type is signaled (see (elisp)Signaling Errors) when the value of expression is unhandled.

A list dispatched to the application of for-in-list to it:

(let ((list '(1 2 3)))
  (for-list ((item list)
             item)))
     ⇒ (1 2 3)

A function dispatched to itself:

(let ((iterator (for-in-list '(1 2 3))))
  (for-list ((item iterator)
             item)))
     ⇒ (1 2 3)

(record '#:some-type) (see (elisp)Special Read Syntax and (elisp)Records) triggers for-unhandled-type:

(let ((some-object (record '#:some-type)))
  (for-list ((item some-object)
             item)))
     error→ Unhandled type: #s(some-type)

Analogous to dynamic dispatch, certain literal objects9 are implicitly wrapped in sequence forms when used in iteration clauses. Currently, literal lists, arrays (see (elisp)Arrays), and integers (see (elisp)Integer Basics) are recognized.

Recognized literal objects are implicitly wrapped in sequence forms:

(for-sum ((number1 '(3 4 5))
          (number2 [6 7 8])
          (number3 3)
          (* number1 number2 number3)))
     ⇒ 108

Footnotes

(9)

Following Common Lisp, a self-evaluating (see (elisp)Self-Evaluating Forms) literal object can be either quoted or unquoted.


Next: Multiple Values, Previous: For Clauses, Up: Basic Concepts   [Contents][Index]