List operations

Collection iteration lets you transform lists and objects without writing explicit loops. The language provides a concise, expression-oriented syntax for mapping over each element or reducing a collection to a single value.

Iteration

The language also supports a map-like iteration form for transforming collections. This is useful when you want to apply the same transformation to every item in a list or object and collect the results.

General shape

The basic idea is:

[ |pattern| expression <- source ]
{ |pattern| expression <- source }
  • Square brackets [...] produce a list.
  • Curly braces {...} produce an object.
  • The pattern is matched against each item in the source.
  • The expression is evaluated once per item, using the matched values.

Map over a list, returning a list

[ |v| v + 3 <- input_list ]

This applies the function |v| v + 3 to each element of input_list. The result is a new list whose values are each transformed by the expression.

Map over an object, returning a list

[ |(k, v)| v + 3 <- input_object ]

When iterating over an object, each item is exposed as a pair of (key, value). This form transforms each value and collects the results into a list.

Map over a list, returning an object

{ |v| (v, "value " + v) <- list }

This form turns each list element into a key/value pair. The first element of the pair becomes the object key, and the second becomes the object value.

Map over an object, returning an object

{ |(k, v)| (k, v + 3) <- object }

This iterates over an object, transforms each (key, value) pair, and builds a new object from the transformed pairs. The result must again be a (key, value) pair for each entry.

Fold

A fold reduces a collection to a single value by repeatedly combining an accumulator with each item. This is useful for things like summing values, concatenating strings, or building a more complex result step by step.

General shape

The general form is:

(|accumulator field| expression <- initial .. source)
  • initial is the starting value of the accumulator.
  • accumulator is the value from the previous step.
  • field is the current item from the collection.
  • The expression returns the next accumulator value.

For example:

(|prev field| (prev * 10 + field) <- 7 .. [1, 2, 3])

This evaluates as:

(((7 * 10 + 1) * 10 + 2) * 10 + 3)

and results in:

7123

Use cases

Fold is a general-purpose building block used to implement many helper functions and utilities. Common uses include:

  • Reducing numeric sequences (sum, product, min/max).
  • Concatenating strings or lists.
  • Accumulating statistics or constructing maps/objects from a collection.
  • Implementing stateful traversals and other higher-level helpers (e.g., group-by, partition, scan).

Because fold exposes both the accumulated state and the current item, it is well suited for composing small reusable functions that operate over collections.

Fold examples: sum and product

# sum: adds all numbers in a list
let
  sum = |lst| (|acc v| acc + v <- 0 .. lst);
in
  sum [1, 2, 3, 4]    # => 10
# product: multiplies all numbers in a list
let
  product = |lst| (|acc v| acc * v <- 1 .. lst);
in
  product [2, 3, 4]   # => 24