2 Experimental Extensions

There are 3 categories of experimental extensions: (1) more general iterators, (2) control extensions, (3) support for loop expressions and accumulation.

2.1 Iterators

Some generators have a syntax which is not yet universally loved. For this reason they are described in this ``experimental section''. Either the user community can suggest a better syntax or we can promote the experimental syntax to official status. However, a proposal that requires the introduction of a new keyword is unlikely to be looked upon favorably.

in I..J ; K

iterates upward from I to J by increments of K.

in Init ; Next

initial value of X is Init. At each subsequent iteration, X is bound to the result of evaluating Next in the current scope of the loop. Thus, an infinite integer iterator starting at I and proceeding by increment of K can be written:

in I ; X+K

For example, instead of

{List.forAllInd L proc {$ I X} ... end}

you can write

for 
   X in L
   I in 1 ; I+1
do 
   ... 
end

2.2 Control

All extensions other than iterators use the new experimental syntax << ... >>. The following extensions permit finer control on the execution of the loop. They may occur in the body of the loop.

<<leave>>
<<leave X>>

immediately terminates the current loop (resp. the loop identified by variable X)

<<while B>>

terminates the current loop when B evaluates to false.

<<until B>>

terminates the current loop when B evaluates to true.

<<next>>
<<next X>>

immediately goes on to the next iteration of the current loop (resp. the loop identified by variable X)

<<named X>>

The current loop is identified by variable X.

2.3 Loop Expressions and Accumulation

Only loop statements are officially supported. However loop expressions are also very convenient; perhaps even more so than statements. In order to turn a loop into an expression, it needs to return a value: for this reason, each loop expression has a ``hidden accumulator''. The content of this accumulator is returned when the loop terminates.

<<collect E>>

the accumulator is of type ``list'' and the value of E is inserted at the end of this list.

<<append L>>

same as above, except that the value of L is appended to the end of the accumulator.

<<count B>>

the accumulator is of type ``integer'' and it is incremented iff B is true.

<<sum N>>

the accumulator is of type ``integer'' and it is incremented by the value of N.

<<maximize N>>

the accumulator is of type ``integer'' and it records the maximal value of N.

<<minimize N>>

the accumulator is of type ``integer'' and it records the minimal value of N.

when <<leave>> is executed in a loop expression, the loop is terminated and the current value of the accumulator is returned.

Here is the loop version of {List.zip L1 L2 fun {$ X Y} ... end}:

for X in L1
    Y in L2
do 
   <<collect ...>> 
end

unlike List.zip, however, it doesn't complain if the lists are of different lengths: it behaves as it the longer one had been truncated to the length of the smaller one.


Denys Duchier
Version 1.1.0 (20000207)