Note: Only numeric range iterators have been implemented.

each makes it easier than while to iterate over a sequence of values. For example, here's the factorial function using each:

fn fact(n i32) i32
  mut result = 1
  each x in 2 ... n
    result *= x
  result

Effectively this each statement binds the variable x to each iterated value from 2 up to n inclusively, each time performing the loop's inner block.

As this example shows, the each statement has a simple structure:

Each clause, break and continue

each may be used as a statement suffix:

fn fact(n i32) i32
  mut result = 1
  result *= x each x in 2 ... n
  result

Also, break and continue statements may be used within an each block to stop or re-start the loop.

Iterators

each supports several ways to iterate over a sequence of values:

Number Range Iterator

As the above example shows, the ... or .. range operator can be used to iterate successively over integers or floating point numbers. Iteration begins with the first number and then increments by 1 until it reaches (..) or passes (...) the second number. Expressions may be used in place of literal numbers, if desired.

To iterate backwards (decrementing the iterated number), use the > or >= operators instead.

each x in 6 > 1  // iterates:  6 5 4 3 2

A step value may be specified after by. Instead of incrementing or decrementing by 1, the step value specifies how much to increase the iterated number each time:

mut sum = 0
each x in 0 ... 10 by 2 // iterates: 0, 2, 4, 6, 8, 10
  sum += x	

Collection Iterator

each can be used to iterate through every element in a collection, one at a time. For example:

mut sum = 0
each x in [4, 3, 8, 2]
  sum += x

Iteration can also capture the index or key for each element value:

each i, x in intslice
  newslice[i] = x

Closure Iterator

Look to closures for iterator versatility. Using closure iterators, one can scan through elements in a complex collection, retrieve values from a streaming resource, algorithmically calculate a sequence of values, etc. Because closures are stateful, they can generate a new value on every call.

In order for a closure to be suitable as an iterator, it must be able to signal when it is done producing values. It typically does this by returning a nullable value, with the value of null signalling when it is done.

In the following example, imagine a closure that starts off holding the value 12, and halves (and returns) its value on each call. When the value gets to 0, it returns null instead:

mut sum = 0
each x in |{cnt = 12}| cnt > 0? Some(cnt /= 2) : null
  sum += x

The value of sum at the end will be 10, as each successive call to the closure returns 6, 3, and 1. After 1, it returns none, which stops iteration.

Because it is stateful, a closure is typically single use. It is created before it is needed, used to produce values lazily, and then discarded afterward. This is because, unless its state can be independently reset, it will only ever afterward say it is out of values.

Automatic Closure Creation

Not uncommonly, we simply want to specify some resource, and have each automatically create a closure for iterating over the collection. For this reason, when a value is specified on each that is not already an iterator, a call to the iter method is implicitly made. iter is expected to return a closure iterator:

each x in collection  // equivalent to: each x in collection.iter

Similarly, if an iterator is expected to return two values, the kviter method is implicitly invoked instead:

each key, value in dictionary

_