Wit

Iteration

(each @list as item) … (end) repeats its body once per item, in order — a menu, a crew list, a route, a set of cards from one collection.

Over records

source
#crew: [
  { name: Ada, role: navigator }
  { name: Bo, role: cook }
] !!

@ul
(each @crew as c)
(li @c.name, @c.role li)
(end)
ul@
result
  • Ada, navigator
  • Bo, cook
<ul><li>Ada, navigator</li><li>Bo, cook</li></ul>

Inside the body, @c is the whole item and @c.name reaches into it. Loop values work as parameter values too: @metric(@m.label, @m.value).

Loop positions

Each item exposes .index (from 0), .count and .last.

source
#crew: [ { name: Ada }, { name: Bo } ] !!

@ol
(each @crew as c)
(li @c.name (@c.index of @c.count) li)
(end)
ol@
result
  1. Ada (0 of 2)
  2. Bo (1 of 2)
<ol><li>Ada (0 of 2)</li><li>Bo (1 of 2)</li></ol>

Positions are values, not arithmetic — for 1-based numbering use @ol, or store the number in the data.

Inline lists with separators

Written inside a sentence, a loop stays inline. Pair it with (if @x.last) to put separators between items only:

#stops: [ Porto, Coimbra, Lisbon ] !!

Route: (each @stops as s)@s(if @s.last)(else) → (end)(end).

That renders Route: Porto → Coimbra → Lisbon. The same shape gives author lists: (if @a.last)(else), (end).

Nesting

Loops nest; the outer item stays visible inside. Point a loop at a list inside a record with a dotted path.

source
#menu: {
  courses: [
    { name: Starters, dishes: [ Soup, Pâté ] }
    { name: Mains, dishes: [ Hake, Risotto ] }
  ]
} !!

(each @menu.courses as c)
(h3 @c.name h3)
@ul
(each @c.dishes as d)
(li @d li)
(end)
ul@
(end)
result

Starters

  • Soup
  • Pâté

Mains

  • Hake
  • Risotto
<h3>Starters</h3><ul><li>Soup</li><li>Pâté</li></ul>
<h3>Mains</h3><ul><li>Hake</li><li>Risotto</li></ul>

Scope

The loop name is local to the body and hides a definition of the same name. After #item: solitary !!, @item outside a loop over as item is solitary; inside it is each element. An empty collection renders nothing.

Errors

  • Iterating a record or a single value is E_NOT_ITERABLE — point at a list, such as @menu.courses.
  • A missing (end) is E_UNCLOSED_STATEMENT.
  • A definition inside a loop is E_CONDITIONAL_DEFINITION.

See also

Conditionals · Data · Additive partials · Self-organising documents