Next: srfi eager-comp spec qualifiers, Up: srfi eager-comp spec [Index]
Evaluate the command exactly once for each binding in the sequence defined by the qualifiers. If there are no qualifiers command is evaluated exactly once. The expression is evaluated for its side–effects only. The result of the comprehension is unspecified.
The list of values obtained by evaluating expression once for each binding in the sequence defined by the qualifiers. If there are no qualifiers the result is the list with the value of expression.
The list obtained by appending all values of expression, which must all be lists. Think of it as:
(apply append (list-ec qualifier* expression))
The string of all values of expression. Think of it as:
(list->string (list-ec qualifier* expression))
The string obtained by appending all values of expression, which must all be strings. Think of it as:
(apply string-append (list-ec qualifier* expression))
The vector of all values of expression. Think of it as:
(list->vector (list-ec qualifier* expression))
The vector of all values of expression, of which there must be
exactly k. This comprehension behaves like vector-ec
but
can be implemented more efficiently.
The sum of all values of expression. Think of it as:
(apply + (list-ec qualifier* expression))
The product of all values of expression. Think of it as:
(apply * (list-ec qualifier* expression))
The minimum and maximum of all values of expression. The sequence of values must be non-empty. Think of these as
(apply min (list-ec qualifier* expression)) (apply max (list-ec qualifier* expression))
If you want to return a default value in case the sequence is empty you may want to consider:
(fold3-ec 'infinity qualifier* expression min min)
Tests whether any value of test in the sequence of bindings
specified by the qualifiers is non–#f
. If this is the case,
#t
is returned, otherwise #f
. If there are no bindings at
all, in the sequence specified by the qualifiers, then the result is
#f
. The enumeration of values stops after the first non–#f
encountered.
Tests whether all values of test are non–#f
. If this is
the case, #t
is returned, otherwise #f
. If the sequence is
empty the result is #t
. Enumeration stops after the first
#f
.
The first or last value of expression in the sequence of bindings
specified by the qualifiers. Before enumeration, the result is
initialized with the value of default; so this will be the result
if the sequence is empty. Enumeration is terminated in first-ec
when the first value has been computed.
Reduce the sequence x[0], x[1], …, x[n-1] of values obtained by evaluating expression once for each binding as specified by qualifier*. The arguments x0, f2, and f1, all syntactically equivalent to expression, specify the reduction process.
The reduction process for fold-ec
is defined as follows. A
reduction variable x is initialized to the value of x0, and
for each k in {0, ..., n-1}
the command:
(set! x (f2 x[k] x))
is evaluated. Finally, x is returned as the value of the comprehension.
The reduction process for fold3-ec
is different. If and only if
n = 0
, i.e. the sequence is empty, then x0 is evaluated and
returned as the value of the comprehension. Otherwise, a reduction
variable x is initialized to the value of (f1 x[0])
, and
for each k in {1, ..., n-1}
the command:
(set! x (f2 x[k] x))
is evaluated. Finally, x is returned as the value of the comprehension.
As the order of the arguments suggests, x0 is evaluated outside the scope of the qualifiers, whereas the reduction expressions involving f1 and f2 are inside the scope of the qualifiers (so they may depend on any variable introduced by the qualifiers). Note that f2 is evaluated repeatedly, with any side–effect or overhead this might have.
The main purpose of these comprehensions is implementing other
comprehensions as special cases. They are generalizations of the
procedures fold
and reduce
in the sense of SRFI-1.
(Concerning naming and argument order, please refer to the discussion
archive of SRFI-1, in particular the posting [Folds].) Note that
fold3-ec
is defined such that x0 is only evaluated in case
the sequence is empty. This allows raising an error for the empty
sequence, as in the example definition of min-ec
below.
An important aspect of this SRFI is a modular mechanism to define
application–specific comprehensions. 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 () [(list-ec etc1 etc ...) (reverse (fold-ec '() etc1 etc ... cons))])) (define-syntax min-ec (syntax-rules () [(min-ec etc1 etc ...) (fold3-ec (min) etc1 etc ... min min)]))
Note that the pattern etc1 ...
matches the syntax
qualifier* 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.
Next: srfi eager-comp spec qualifiers, Up: srfi eager-comp spec [Index]