| << Prev | - Up - |
There are 3 categories of experimental extensions: (1) more general iterators, (2) control extensions, (3) support for loop expressions and accumulation.
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.
X in I..J ; K iterates upward from I to J by increments of K.
X 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:
X inI; 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
...
endAll 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.
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.
| << Prev | - Up - |