A generator is a function that produces a potentially-infinite stream of values. Each time the function produces a value, it suspends itself and waits for a caller to request the next value.
iter-defun defines a generator function. A generator function
has the same signature as a normal function, but works differently.
Instead of executing body when called, a generator function
returns an iterator object. That iterator runs body to generate
values, emitting a value and pausing where
iter-yield-from appears. When body returns normally,
iter-end-of-sequence with body’s
result as its condition data.
Any kind of Lisp code is valid inside body, but
iter-yield-from cannot appear inside
iter-lambda produces an unnamed generator function that works
just like a generator function produced with
When it appears inside a generator function,
indicates that the current iterator should pause and return
iter-yield evaluates to the
value parameter of next call to
iter-yield-from yields all the values that iterator
produces and evaluates to the value that iterator’s generator
function returns normally. While it has control, iterator
receives values sent to the iterator using
To use a generator function, first call it normally, producing a
iterator object. An iterator is a specific instance of a
generator. Then use
iter-next to retrieve values from this
iterator. When there are no more values to pull from an iterator,
iter-next raises an
iter-end-of-sequence condition with
the iterator’s final value.
It’s important to note that generator function bodies only execute
inside calls to
iter-next. A call to a function defined with
iter-defun produces an iterator; you must drive this
iter-next for anything interesting to happen.
Each call to a generator function produces a different
iterator, each with its own state.
Retrieve the next value from iterator. If there are no more
values to be generated (because iterator’s generator function
iter-next signals the
condition; the data value associated with this condition is the value
with which iterator’s generator function returned.
value is sent into the iterator and becomes the value to which
iter-yield evaluates. value is ignored for the first
iter-next call to a given iterator, since at the start of
iterator’s generator function, the generator function is not
If iterator is suspended inside an
bodyform and becomes unreachable, Emacs will eventually run
unwind handlers after a garbage collection pass. (Note that
iter-yield is illegal inside an
unwindforms.) To ensure that these handlers are run before
Some convenience functions are provided to make working with iterators easier:
Run body with var bound to each value that iterator produces.
The Common Lisp loop facility also contains features for working with iterators. See Loop Facility in Common Lisp Extensions.
The following piece of code demonstrates some important principles of working with iterators.
(require 'generator) (iter-defun my-iter (x) (iter-yield (1+ (iter-yield (1+ x)))) ;; Return normally -1) (let* ((iter (my-iter 5)) (iter2 (my-iter 0))) ;; Prints 6 (print (iter-next iter)) ;; Prints 9 (print (iter-next iter 8)) ;; Prints 1; iter and iter2 have distinct states (print (iter-next iter2 nil)) ;; We expect the iter sequence to end now (condition-case x (iter-next iter) (iter-end-of-sequence ;; Prints -1, which my-iter returned normally (print (cdr x)))))