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