On this page:
for
each
keep_  when
skip_  when
break_  when
final_  when
8.12

6.15 Iteration🔗ℹ

expression

for maybe_each:

  clause_or_body

  ...

  body

 

expression

for reducer maybe_each:

  clause_or_body

  ...

  body

 

expression

for maybe_each:

  clause_or_body

  ...

  body

  ~into reducer

 

maybe_each

 = 

(bind:

   body

   ...,

 ...)

 | 

ϵ

 

clause_or_body

 = 

each bind:

  body

  ...

 | 

each:

  bind:

    body

    ...

  ...

 | 

keep_when expr_or_block

 | 

skip_when expr_or_block

 | 

break_when expr_or_block

 | 

final_when expr_or_block

 | 

other_for_clause

 | 

body

 

expr_or_block

 = 

expr

 | 

: body; ...

Iterates as determined by maybe_each and each clauses among the clause_or_bodys, where a non-empty maybe_each is converted to an initial each before all clause_or_bodys. An each clause forms one layer of iteration; each subsequent part of the body is evaluated once per iteration, and additional each groups form nested iterations.

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 prenthesized 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 remining 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 reminaing 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"]

    keep_when v == "b"

    println(v)

b

> for:

    each v: ["a", "b", "c"]

    skip_when v == "b"

    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..):

    println(i +& ". " +& v)

0. a

1. b

2. c

> for:

    each:

      v: ["a", "b", "c"]

      i: 0..

    println(i +& ". " +& v)

0. a

1. b

2. c

> fun grid(m, n):

    for List:

      each i: 0..m

      each j: 0..n

      [i, j]

> grid(2, 3)

[[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2]]

> fun sum(l :: List):

    for values(sum = 0):

      each i: l

      sum+i

> sum([2, 3, 4])

9

> for:

    each i: [1, 2, 3]

    each j: 10..10+3

    [i, j]

    ~into List

[

  [1, 10],

  [1, 11],

  [1, 12],

  [2, 10],

  [2, 11],

  [2, 12],

  [3, 10],

  [3, 11],

  [3, 12]

]

> for values(x = 0, y = 2):

    each j: 0..3

    values(x + y, j)

3

2

> fun grid2(m, n):

    for List:

      each i: 0..m

      let k = i + 1

      each j: 0..n

      [k, j]

> grid2(2, 3)

[[1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]

> for Map (i: 0..3):

    values(i, i +& "!")

{0: "0!", 1: "1!", 2: "2!"}

> for Map:

    each i: 0..3

    values(i, i +& "!")

{0: "0!", 1: "1!", 2: "2!"}

for clause

each:

  bind:

    body

    ...

  ...

 

for clause

each bind:

  body

  ...

 

for clause

keep_when expr

 

for clause

keep_when: body; ...

 

for clause

skip_when expr

 

for clause

skip_when: body; ...

 

for clause

break_when expr

 

for clause

break_when: body; ...

 

for clause

final_when expr

 

for clause

final_when: body; ...

The primitive clause forms that are recognized by for.