Previous page Table of Contents Next page
If you like list comprehensions they are easy to implement for yourself. Here is an example definition that uses essentially the same syntax as Python:
defmacro \{ ?value { for ?:variable in ?list | if ?test }+ \} => ;; wrap up nested fors and ifs def wrapper := `` for v in variable, l in list, t in test if l wrapper := `?wrapper for ?v in ?l` else wrapper := `?wrapper if ?t` ;; expansion does the iterations, accumulating results in a stack `block def result = stack() ?wrapper result.push := ?value result.bottom-up`
Now you can write things like:
{ 2 * x for x in 0 : 100 if x ^ 2 > 3 } { i for i in 0 : 10 } { i for i in 0 : 10 if i mod 2 = 0 } ;; nested iteration example def nums = 1 : 4 def fruits = #("Apples" "Peaches" "Pears" "Bananas") { list(i, f) for i in nums for f in fruits } { list(i, f) for i in nums for f in fruits if f[0] = 'P' } { list(i, f) for i in nums for f in fruits if f[0] = 'P' if i mod 2 = 1 }
You can also define a syntax closer to standard mathematical notation allowing you to write, for example:
{ list(i, f) | i in nums, f in fruits, f[0] = 'P', i mod 2 = 1 }
The definition of this list comprehension syntax is
defmacro \{ ?value \| { ?test [ in ?list ] & ~^ , }+ \} => ;; wrap up nested fors and ifs def wrapper := `` for l in list, t in test if l if not t is name error(#"invalid variable name ?t in list comprehension") wrapper := `?wrapper for ?t in ?l` else wrapper := `?wrapper if ?t` ;; expansion does the iterations, accumulating results in a stack `block def result = stack() ?wrapper result.push := ?value result.bottom-up`
Note the trick of parsing an iteration variable as an expression and then reporting an error if the expression is not just a name. This makes it possible to parse the syntax with only one-token lookahead, i.e. LL(1).
For this use of | to work, you must not import the standard | operator from the PLOT module into your module.
Alternatively you could give value the syntactic type expression-no-vbar and define parse-expression-no-vbar as a modified copy of parse-expression which does not recognize | as an infix operator. Any use of that operator would have to be enclosed in parentheses.
Previous page Table of Contents Next page