Next: , Previous: , Up: loops generators   [Index]


1.16.4.3 Typed generators

Generator Syntax: :list vars arg0 arg ...
Generator Syntax: :string vars arg0 arg ...
Generator Syntax: :vector vars arg0 arg ...

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))
Generator Syntax: :integers vars

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.

Application specific typed generator

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: , Previous: , Up: loops generators   [Index]