Sometimes you want to iterate across two lists in parallel, or perhaps you want to traverse a list while incrementing a variable.
The general syntax of a repeat loop is
iterator1, iterator2, ..., iteratorN repeat loopbody
where each iterator is either a for or a while clause. The loop terminates immediately when the end test of any iterator succeeds or when a leave or return expression is evaluated in loopbody. The value returned by the loop is the unique value of Void.
l := [1,3,5,7]
[1,3,5,7]
Type: List PositiveInteger
m := [100,200]
[100,200]
Type: List PositiveInteger
sum := 0
0
Type: NonNegativeInteger
Here we write a loop to iterate across two lists, computing the sum of the pairwise product of the elements:
for x in l for y in m repeat
sum := sum + x*y
Type: Void
The last two elements of l are not used in the calculation because m has two fewer elements than l.
sum
700
Type: NonNegativeInteger
This is the “dot product”.
Next we write a loop to compute the sum of the products of the loop elements with their positions in the loop.
l := [2,3,5,7,11,13,17,19,23,29,31,37]
[2,3,5,7,11,13,17,19,23,29,31,37]
Type: List PositiveInteger
sum := 0
0
Type: NonNegativeInteger
for i in 0.. for x in l repeat sum := i * x
Type: Void
Here looping stops when the list l is exhaused, even though the for i in 0.. specifies no terminating condition.
sum
407
Type: NonNegativeInteger
When “|” is used to qualify any of the for clauses in a parallel iteration, the variables in the predicates can be from an outer scope or from a for clause in or to the left of the modified clause.
This is correct:
for i in 1..10 repeat
for j in 200..300 | ood? (i+j) repeat
output [i,j]
But this is not correct. The variable j has not been defined outside the inner loop:
for i in 1..01 | odd? (i+j) repeat -- wrong, j not defined
for j in 200..300 repeat
output [i,j]
It is possible to mix several of repeat modifying clauses on a loop:
for i in 1..10
for j in 151..160 | odd? j
while i + j < 160 repeat
output [i,j]
[1,151]
[3,153]
Type: Void
Here are useful rules for composing loop expressions:
- while predicates can only refer to variables that are global (or in an outer scope) or that are defined in for clauses to the left of the predicate.
- A “such that” predicate (somthing following “|”) must directly follow a for clause and can only refer to variables that are global (or in an outer scope) or defined in the modified for clause or any for clause to the left.