411 REFERENCE · Wikibooks
The Sway Reference Manual/Loops
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Sometimes, a programmer wishes to execute a section of code multiple
times. This kind of task is commonly performed using a loop.
The most
basic loop structure in Sway is the while loop, whose format is...
whileloop: 'while' '(' expr ')' block
where expr is any Sway expression that resolves to the
symbols :true or :false.
A while loop tests its condition before the body of the loop is
executed. If the initial test fails, the body is not executed at all. For
example;
var i = 10;
while (i < 10)
{
print(i);
i = i + 1;
}
never prints out anything since the test immediately fails. In this example,
however:
var i = 0;
while (i < 10)
{
print(i);
i = i + 1;
}
the loop prints out the digits 0 through 9:
0123456789
A while loop executes its body (the block portion of the loop)
repeatedly (as long as the condition remains true).
To write an infinite loop, use :true as the test expression:
while (:true)
{
var i = getInput();
process(i);
}
Loops are function calls
As with if, all Sway loops are function calls, usually
with proximal block arguments. If desired, small proximal
blocks can be moved inside the parentheses as regular arguments.
Also, the semicolon rule for if applies to loops as well:
A loop, by itself, having a proximal block argument is not
followed by semicolon. If you were to use the return
value of a loop (for while, it is :true if the test expression
was initially true and :false if the test expression was
initially false), you would need to terminate the entire
expression with a semicolon.
Other loops
Because loops are so easy to write in Sway, only the while loop
is built-in. Other loops can be found in the "basics" library.
To use the "basics" library, add the function call:
include("basics");
at the top of your source code file.
do-until
The do-until loop is similar to the while loop, but the body
of the loop is executed once before the test is made. For example:
var i = 10;
do-until (i == 10) //note the test
{
print(i);
i = i + 1;
}
prints out the value of i once:
10
Note that the do-until runs until the test succeeds, which is
the opposite of the while, which runs until the test fails.
The do-until loop is not used very often,
though sometimes it is useful for processing interactive input.
You can always write a do-until as a while loop. Consider
this loop:
do-until (r == 0)
{
r = n / d;
n = d;
d = r;
}
It can be rewritten as a while loop thusly...
finished = :false;
while (!finished)
{
r = n / d;
n = d;
d = r;
finished = (r == 0);
}
Note that the variable finished, being initialized to :false,
ensures that the body of the loop is entered at least once.
At the bottom of the loop, finished is set to the
do-until test result.
Usually, the do-until is easier to read and understand.
for loops
Another loop found in many programs is the for loop.
The for loop is composed of four major parts:
the initialization step
the test
the body
the update
Note that these components correspond exactly to a while loop
i = 0; // initialize
while (i < MAX) // test
{ // body
inspect(i);
i = i + 1; // update (in body)
}
with the update usually being the last statement in
the loop body. The corresponding for loop is:
for (i = 0, i < MAX, i = i + 1) // init, test, update
{ // body
inspect(i);
}
See how the update has been moved out of the body.
For loops are commonly used to sweep through each element of an array:
for (i = 0, i < length(items), i = i + 1)
{
a[i] = b[i] * c[i];
}
The for loop is a counting loop.
With most, but not all,
counting loops,
the loop
variable (in this case i)
is initialized to zero and the loop test
(in this case i < length(items))
is configured to succeed
as long as the loop variable is
strictly less than maximum of the count.
If the loop body is to be executed n times,
then the loop would look something like:
for (i = 0, i < n, i = i + 1)
{
...
}
This convention
stems from the fact that arrays in Sway
(detailed in a later chapter)
use 'zero-based indexing'. That is to say,
the first element of an array is located at index
zero, the second at index one and so on.
You should always use this convention unless there is
good reason not toJust trust me on this one..
for-each loops
The for-each loop is also useful for sweeping through arrays and lists. It does so without explicitly counting, however:
for-each (s,items)
{
inspect(s);
}
In this loop, each element in items is bound to the variable
s, in turn. The loop body executes as many times as there
are elements in the array or list. Note how much shorter the
for-each loop is compared to the equivalent for loop:
for (i = 0; i < length(item); i = i + 1)
{
var s = items[i];
inspect(s);
}
which explicitly counts.
Leaving loops
There are
numerous ways to leave a loop, besides having the
loop condition or test failing (or succeeding in the case of
the do-until). It is possible to return from a function
even if in the middle of a loop. This technique is often
used when searching an array:
function find(x,items)
{
var s;
for-each(s,items)
{
if (x == s)
{
return :true;
}
}
:false;
}
Note that if the item isn't found, the loop eventually terminates
and failure is noted by returning :false.
You can also leave a loop without leaving the function completely
by calling break:
i = 0;
while (i < 10)
{
if (i > 5) { break(); }
inspect(i);
}
println(:done);
Running this code yields:
i is 0
i is 1
i is 2
i is 3
i is 4
i is 5
done
You will need to include basics to use break. You could also
just throw an exception of type :break instead:
i = 0;
while (i < 10)
{
if (i > 5) { throw(:break,0); }
inspect(i);
}
println(:done);
Finally, you can leave a loop by leaving the program via the
exit function:
while (1)
{
var input = getInput();
if (reallyBad(input))
{
exit(-1); //non-zero exit code
}
}
By convention, Sway programs that exit with code of zero
means processing went normally. A non-zero exit code
indicates that some sort of fatal error occurred.
Footnotes
Conditionals Recursion