Skip to the content.

for loops and iterators

Basic syntax

for (x in 0 until 1e7) do
    ...

(from range_test.ar)

for (item in iterable) do ... iterates over anything iterable — arrays, ranges, strings, dictionaries, or any custom object that implements the iterator protocol described below.

for (item in [1, 2, 3]) do
    term.log(item)

Ranges

a until b produces a range you can loop over. The standard library also exposes a range(...) function (used e.g. in map_filter_sort.ar as range(-1000000, 1000000)), which is the built-in range type (ARGON_RANGE_ITERATOR_TYPE) constructed directly.

The iterator protocol

Any object can be made iterable by implementing two dunder methods:

Here’s a full custom range implementation from the test suite:

class custom_range_iterator do
    this.__init__(self, stop) = do
        self.current = 0
        self.stop = stop
    this.__next__(self) = do
        if (self.stop <= self.current) do
            throw StopIteration()
        let result = self.current
        self.current = self.current + 1
        return result

class custom_range do
    this.__init__(self, stop) = do
        self.stop = stop
    this.__iter__(self) = custom_range_iterator(self.stop)

for (x in custom_range(1e4)) do
    for (y in custom_range(1e3)) do
        ...

(from custom_range.ar)

StopIteration is one of the built-in system exceptions (see Errors and exceptions) and is how iterators signal “no more values” — it’s caught internally by the for loop machinery, not something you usually need to catch yourself.

Nested loops

Loops can be nested arbitrarily, as shown in the custom_range example above.

Next