A loop is an iteration: a process that repeats an operation a number of times to perform repetitive tasks, accumulation, collection of data, etc. Loops are not the easiest thing to do in OM#, but they can become a powerful ally.
See also:
mapcar
is a nice an also powerful alternative to the OM# loop feature in many cases. It is often a matter of style!
iterate
Loops in OM# are standard patches (with any number of inputs and outputs) including one or more iterate
boxes.
Each iterate
box accounts for a loop.
iterate
evaluates its input(s) a number of time as determined by the loop iterators (loop-for
, loop-list
, loop-tail
, loop-while
) that are connected to it, either directly or indirectly. The example below prints the elements in a list:
The iterate
box can have an arbitrary number of inputs, which are evaluated from left to right and allow for combining iterators and the sequencing of actions inside the loop.
iterate
triggers evaluation, but does not return a value from the patch, as standard outputs / out
boxes do.
The iterations therefore generally produce side-effects (print
is one of them) or data collection (for instance using collect
or accum
, whose value can be returned by the patch outputs) (see below, data collection).
While editing a loop, it is possible to get a “preview” of the iteration result by evaluating the iterate
box.
The list displayed in the listener here is however a display artifact, as iterate
by itself does not collect any data.
loop-for
, loop-list
, loop-tail
, loop-while
There exist 4 different iterators:
loop-list
iterates on the successive elements of a listloop-tail
iterates on the tail of a list, popping out the first element each timeloop-for
iterates between two numbersloop-while
iterates while a given condition is trueOptional inputs in iterators
Some iterators (
loop-for
,loop-list
,loop-tail
) have an optional input calledby
. This parameter controls the iteration with more advanced criteria.The meaning is somehow straightforward in the case of
loop-for
: iterate from a to b by n (the default is 1).With
loop-list
andloop-tail
,by
is a function determining how to get the next state of the list (the default iscdr
: we just pop the first element out).
Several iterators can be combined and connected to a same iterate
box.
This is when loops start to be more expressive and powerful than usual map...
iterators.
The iteration stops as soon as one of the iterator finishes:
This makes sense in particular for the loop-while
iterator, which essentially works connected to other iterators.
Note: Iterator values are not valid outside of the
iterate
context. It is an error to connect it directly to a loop output, for instance. In order to return the last value of an iterator, use a memory box likemem
orcollect
(see below).
One of the main use of loops in OM# will be the iterative processing and collection of data.
collect
(or accum
, for more advanced use) are iterate
’s best friends for that purpose.
collect
box to iterate
, in order to collect/accumulate data in memory.collect
box to an output to return the collected data at the end of the loop.See also: Memory → More on
collect
/accum
When a patch containing an iterate
box is evaluated, the following actions happen in order:
init-do
boxes (if any).
init-do
is a special box specifying actions to perform before iteration starts (for instance preparing initial states).iterate
boxesout
boxes (just like in a standard patch)Hint: Up to a certain level of complexity, the Lisp code visualization feature can be useful to understand what the loop-abstraction is doing.