# Loops and the Iteration Protocol¶

Monte has only two kinds of looping constructs: `for` loops, which consume iterators to process a series of elements, and `while` loops, which repeatedly consider a predicate before doing work. Both should be familiar to any experienced programmer; let’s explore them in greater detail.

## `for` loops¶

A `for` loop is a simple structure that takes an iterable object and loops over it:

```var x := 0
for i in (1..10):
x += i
```

Here, we can clearly see the three elements of the `for` loop, the pattern, `x`; the iterable, `1..10`, and the loop’s body, `x += i`. For each element in the iterable, the iterable is matched against the pattern, which is available within the body.

Within a `for` loop, the `continue` keyword will skip the current iteration of the loop, and `break` keyword will exit the loop altogether:

```# Skip the even elements, and give up if we find multiples of three.
for i in (1..10):
if (i % 2 == 0):
continue
if (i % 3 == 0):
break
x -= i
```

### Pair Patterns¶

All iterables yield not just one element, but a pair of elements on every iteration. To access both elements at once, we can use a pair pattern:

```def names := ["Scooby", "Shaggy", "Velma"]
for i => name in (names):
traceln(`Name \$i: \$name`)
```

For a list, like in the previous example, the right-hand side of the pair matches the current element, and the left-hand side matches that element’s index. When iterating over a map, the pair will match the key and value:

```def animals := [
"Bagira"     => "panther",
"Baloo"      => "bear",
"Shere Khan" => "tiger",
]
for animal => species in (animals):
traceln(`Animal \$animal is a \$species`)
```

## `while` loops¶

In addition to the `for` loop, Monte provides a `while` loop:

```var x := 1
while (x < 402):
x *= 2
```

The `while` loop admits `continue` and `break`, just like in `for` loops.

### The Secret Lives of Flow Control Structures¶

Flow control structures actually return values. For example, the if-else returns the last value in the executed clause:

```def a := 3
def b := 4
def max := if (a > b) {a} else {b}
```

This behavior is most useful when used with the when-catch construct described in the When-expressions and Delayed Actions section. The break statement, when used in a for or a while loop, can be followed by an expression, in which case the loop returns the value of that expression.

### Loops as Expressions¶

Like all structures in Monte, `for` loops are expressions; they return values:

```def result := for value in (0..10) { value }
```

Here, `result` is `null`, which is the default return value for `for` loops. To override that value, use `break`:

```def result := for value in (0..10) { break value }
```

Since `break` was used, the loop exits on its first iteration, returning `value`, which was `0`. So `result` is `0`.

### List & Map Comprehensions¶

`for` loops aren’t the only way to consume iterable objects. Monte also has comprehensions, which generate new collections from iterables:

```[for value in (iterable) transform(value)]
```

This will build and return a list. Maps can also be built with pair syntax:

```[for key in (keyList) key => makeValue(key)]
```

And, of course, pair syntax can be used for both the pattern and expression in a comprehension:

```[for key => value in (reverseMap) value => key]
```

Additionally, just like in Python and Haskell, comprehensions support filtering with a predicate; this is called the for-such comprehension:

```>>> def evens := [for number in (1..10) ? (number % 2 == 0) number]
... evens
[2, 4, 6, 8, 10]
```

Just like the such-that pattern, this such-that clause is evaluated for every iteration, and iterations where the clause returns `false` are skipped. Also, just like the such-that pattern, and unlike some other languages’ comprehension syntax, the predicate must return a `Bool`; if it doesn’t, then the entire comprehension will fail with an exception.

Monte has an iteration protocol which defines iterable and iterator objects. By implementing this protocol, it is possible for user-created objects to be used in `for` loops and comprehensions.

Iterables need to have `to _makeIterator()`, which returns an iterator. Iterators need to have `to next(ej)`, which takes an ejector and either returns a list of `[key, value]` or fires the ejector with any value to end iteration. Guards do not matter but can be helpful for clarity.

As an example, let’s look at an iterable that counts upward from zero to infinity:

```object countingIterable:
to _makeIterator():
var i := 0
return object counter:
to next(_):
def rv := [i, i]
i += 1
return rv
```

Since the iterators ignore their ejectors, iteration will never terminate.

For another example, let’s look at an iterator that wraps another iterator and only lets even values through:

```def onlyEvens(iterator):
return object evens:
to next(ej):
var rv := iterator.next(ej)
while (rv[1] % 2 != 0):
rv := iterator.next(ej)
return rv
```

Note that the ejector is threaded through `to next(ej)` into the inner iterator in order to allow iteration to terminate if/when the inner iterator becomes exhausted.