Loops (advanced)
Loop success and failure
A typical application of a loop is searching for one element with certain properties in some set of data. As a simple example, assume we implement a routine that uses a loop to find the first integer in a given interval that is divisible by another integer. A naïve implementation is shown here:
This code is admittedly ugly. A boolean field found
is introduced to
record the fact that a solution was found and printed, and this flag needs to be
initialized to false
and checked repeatedly as the while
condition and after the loop.
An alternative to the while
condition is a termination condition using
until
that is not executed before, but after the loops body has been
executed. The above example can be cleaned up slightly using until
:
But the code is still not satisfactory. The main issue is that the loop can
exit due to two reasons, either success -when a divisible number was found-,
or failure -if none was found. To handle these two cases after the loop, we
had to introduce another variable last_i
since i
is
visible within the loop only.
In Fuzion, it is possible to add code for a successful or a failed loop
execution right after the until
condition of the loop. Any loop with
an until clause terminates successfully if the loop's until
clause is
true after execution of the loops body.
Alternatively, a loop fails if it terminates due to a different reason, which
can be either be the while
condition being false or any of the index
variables that iterates over a stream reaching the end of that stream.
An else
clause after the loop will be executed after a loop
failed.
Making use of code blocks executed on loop success and failure, the example becomes significantly simpler and clearer:
Since the loop's body is an empty do { }
block now, it can be
omitted and we get to our final version:
You might have noticed that there is no need to declare any variables outside of
the loop. Index variables declared in the for
part of the loop are
also visible in the success block after the until
condition. However, only those index variables declared before the first
iterating index variable are accessible in the else
clause since
iterating index variables would be undefined if the iteration was exhaustive.
Several iterating index variables
A loop may perform several iterations at the same time. The following
example shows a loop that iterates over the elements of an array and the
elements of two intervals. Additionally, an index variable res
is a growing list containing the result.
In case of several iterating variables, the loop terminates as soon as one
of these variables runs out of values to iterate over. Consequently, in
an else
clause, only loop index variables declared before the first
iterating variable are defined and may be used.