Simple counting loops
Let's start with a simple loop that counts to 10 using a loop index variable:
The index field
i is initially set to
each loop iteration, it will be set to the previous value plus one
i + 1. The loop body prints the value of this index field
say i, and this body is executed repeatedly as long
i <= 10 holds.
Even though it appears as if the index field
i is assigned a
new value during each loop iteration, the code does not mutate fields. Each
loop iteration creates a new instance of
i which is not
Not mutating the index field has an enormous advantages: The field is an immutable field within the loop body, which allows for compiler optimizations and for cheap accesses within closures, even accesses from other threads are automatically safe.
The loop termination condition that so far was given in the
part can be omitted to create an endless loop, as shown in the next example:
An endless loop is typically not very useful, the main exception being the control loop in a task that is supposed to continue forever.
However, as we will see next, iterating loops that operate over a finite stream of elements do not need an explicit termination condition, which will be shown in the following examples.
Using a simple iterating loop enables us to further simplify the code of the previously presented counting loop by iterating over an interval:
What happens here is logically different from the previous loops: The expression
1..10 calls the feature
infix .. on the integer constant
1 with the argument
10. This feature defines an interval from
the value it is called on to the value passed as an argument. So, in this case,
this defines an interval from 1 to 10, inclusive.
An interval is a List, which means that it can be used to define a loop
index field using
What this means is that the previous example uses syntactic sugar that the compiler expands to something like the following
This looks as if the code could be significantly slower to run than the simple index field in the earlier examples. However, the compiler's optimization will result in code that is almost identical.
The ability to loop over arbitrary streams of indices enables as well to loop
over integers using a step size larger than 1. Here is an example that prints
only even numbers by using a step of
This loop is essentially the same as the previous loop, only that the interval
that the loop iterates over now was created using a step size, which is done
using the operator
infix : on an integer interval.