Parallel IterationΒΆ

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:

  1. 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.
  2. 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.

Table Of Contents

This Page