Previous: loops comprehensions fold, Up: loops comprehensions [Index]
To create a new comprehension a hygienic macro with that name is
defined. The macro transforms the new comprehension patterns into
instances of do-ec, which is the most fundamental eager
comprehension, or any other comprehension already defined.
For example, the following code defines list-ec and min-ec
in terms of fold-ec and fold3-ec:
(define-syntax list-ec
(syntax-rules ()
((_ ?etc1 ?etc ...)
(reverse (fold-ec '() ?etc1 ?etc ... cons)))))
(define-syntax min-ec
(syntax-rules ()
((_ ?etc1 ?etc ...)
(fold3-ec (min) ?etc1 ?etc ... min min))))
Note that the pattern ‘?etc1 ...’ matches qualifier* and expression without separate access to qualifier* and expression. In order to define a comprehension that does need explicit access to the expression part, the following method is used.
First, all qualifiers are collected into a nested–qualifier, and then
the “exactly one qualifier” case is implemented. For illustration,
the following code defines fold3-ec in terms of do-ec:
(define-syntax fold3-ec
(syntax-rules (nested)
((fold3-ec x0 (nested q1 ...) q etc1 etc2 etc3 etc ...)
(fold3-ec x0 (nested q1 ... q) etc1 etc2 etc3 etc ...))
((fold3-ec x0 q1 q2 etc1 etc2 etc3 etc ...)
(fold3-ec x0 (nested q1 q2) etc1 etc2 etc3 etc ...))
((fold3-ec x0 expression f1 f2)
(fold3-ec x0 (nested) expression f1 f2))
((fold3-ec x0 qualifier expression f1 f2)
(let ((result #f)
(empty #t))
(do-ec qualifier
(let ((value expression)) ; don't duplicate code
(if empty
(begin
(set! result (f1 value))
(set! empty #f))
(set! result (f2 value result)))))
(if empty x0 result)))))
Finally, observe that the newly defined fold3-ec comprehension
inherits all types of qualifiers supported by do-ec, including
all application–specific generators; no further definitions are
necessary.