8.8 Iteration
expression | ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
expression | ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
expression | ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||
|
The block after a binding within an each clause must produce a sequence. When for is static (see use_static), static information for the block must indicate a static sequence implementation that may specialize iteration over the sequence; see also Sequence and statinfo_meta.sequence_constructor_key. A fresh instantiation of the sequence is used each time the for form is evaluated. Each element of that sequence is bound in turn to the bind variables of the each. If a sequence can has multiple values as its elements (for example, a map as a sequence has a key and value for each element), then bind can be a values pattern or just a parenthesized sequence of bindings to receive a matching number of element values.
An each followed immediately by a sequence binding is equivalent to each followed immediately by a block that contains the sequence binding. When multiple sequences are used in one iteration layer (i.e., in a block immediately after each), iteration stops as soon as one of the sequences in the layer is exhausted.
A keep_when or skip_when clause short-circuits one iteration of the for body, skipping remaining expressions (including nested iterations) when the subsequent expr produces #false for keep_when or a true value for skip_when. A break_when clause short-circuits the current iteration and all would-be remaining iterations of the for form when its expr produces a true value. A final_when clause is similar to keep_when, but it allows one iteration to complete before skipping the remaining iterations.
New for clause forms can be defined as macros that (eventually) expand to the core forms that are recognized by for.
If a reducer is specified, either before the block or at the end with ~into, it determines how each result of the last body is combined to produce a result of the overall for expression, otherwise the result of the last body is ignored and the for expression’s value is #void. Example reducers include List, Map, and values.
> for (v: ["a", "b", "c"]):
println(v)
a
b
c
> for:
each v: ["a", "b", "c"]
println(v)
a
b
c
> for:
each v: ["a", "b", "c"]
println(v)
b
> for:
each v: ["a", "b", "c"]
println(v)
a
c
> for:
each v: ["a", "b", "c"]
break_when v == "b"
println(v)
a
> for:
each v: ["a", "b", "c"]
final_when v == "b"
println(v)
a
b
> for (v: ["a", "b", "c"],
i: 0..):
0. a
1. b
2. c
> for:
each:
v: ["a", "b", "c"]
i: 0..
0. a
1. b
2. c
> fun grid(m, n):
[i, j]
> grid(2, 3)
[[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2]]
> for:
each i: [1, 2, 3]
[i, j]
~into List
[
[1, 10],
[1, 11],
[1, 12],
[2, 10],
[2, 11],
[2, 12],
[3, 10],
[3, 11],
[3, 12]
]
> fun grid2(m, n):
[k, j]
> grid2(2, 3)
[[1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
{0: "0!", 1: "1!", 2: "2!"}
{0: "0!", 1: "1!", 2: "2!"}
for clause | |||||
| |||||
| |||||
for clause | |||||
| |||||
| |||||
for clause | |||||
| |||||
for clause | |||||
| |||||
for clause | |||||
| |||||
for clause | |||||
| |||||
for clause | |||||
| |||||
for clause | |||||
| |||||
| |||||
for clause | |||||
| |||||
for clause | |||||
|