Next: loops generators ranges, Previous: loops generators do, Up: loops generators [Index]
Run through one or more lists, strings, or vectors. First all the arg expressions are evaluated and then all elements of the resulting values are enumerated from left to right. One can think of it as first appending all arguments and then enumerating the combined object.
(list-ec (:string c (index i) "a" "b") (cons c i)) ⇒ ((#\a . 0) (#\b . 1)) (list-ec (:string c (index i) "ciao" "mamma") (cons c i)) ⇒ ((#\c . 0) (#\i . 1) (#\a . 2) (#\o . 3) (#\m . 4) (#\a . 5) (#\m . 6) (#\m . 7) (#\a . 8))
Runs through the sequence 0, 1, 2, … of non–negative integers. This is most useful in combination with ‘:parallel’, ‘:while’, and ‘:until’ or with a non–local exit in the body of the comprehension.
To define a new typed generator a hygienic referentially transparent macro of the same name is defined to transform the generator pattern into an instance of the ‘:do’ generator. The extension is fully modular, meaning that no other macro has to be modified to add the new generator. This is achieved by defining the new macro in Continuation Passing Style.
Technically, this works as follows. Assume the generator syntax:
(:mygen var arg)
is to be implemented, for example running the variable var through
the list (reverse arg)
. The following definition
implements :mygen
in terms of ‘:list’ using the additional
syntactic variable cc (read current continuation):
(define-syntax :mygen (syntax-rules () ((:mygen cc var arg) (:list cc var (reverse arg)))))
After this definition, any comprehension will accept the :mygen
generator and produce the proper code for it. This works as follows.
When a comprehension sees something of the form (g arg
...)
in the position of a ?qualifier then it will transform the
entire comprehension into:
(g (continue ...) arg ...)
This effectively “transfers control” to the macro g, for example ‘:mygen’. The macro g has full control of the transformation, but eventually it should transform the expression into:
(:do (continue ...) etc ...)
In the ‘:mygen’ example this is done by the ‘:list’ macro. The macro ‘:do’ finally transforms into:
(continue ... (:do etc ...))
As ‘continue’ has been chosen by the macro implementing the comprehension, it can regain control and proceed with other qualifiers.
In order to ensure consistency of new generators with the ones defined
in (vicare language-extensions loops)
, a few conventions are in
order.
Next: loops generators ranges, Previous: loops generators do, Up: loops generators [Index]