The for expressions, sometimes called for loops, are the same as loop expressions, except that for expressions iterate over a bounded number of items. This means the number of iterations is known before the for loop is executed, and decisions on when to exit the loop are automated for you.
The Pulse Trigger device is an example of a for loop with bounded iterations when you set the Pulse Trigger device Looping setting to a number. The Pulse Trigger's pulse repeats as many times as specified by the device Looping setting.
In this example, two Trigger devices are in the Pulse Trigger's path. When the Pulse Trigger's pulse reaches a Trigger device, the device sends a signal to display text on one of the
As code, this example could look like:
for (X := 0..2):
TriggerDevice1.Transmit()
TriggerDevice2.Transmit()The for expression contains two parts:
Iteration specification: The expressions within the parentheses and the first expression must be a generator. In this example, it is
(X := 0..2).Body: The expressions after the parentheses. In this example, that is the two lines with
Transmit().
Generator
A generator produces a sequence of values, one at a time, and gives the value a name. In this example, the generator is X := 0..2, so each iteration of the loop, the generator produces the next value and gives the value the name X. When the generator reaches the end of the sequence, the for loop ends. This decision flow of checking if the loop variable has a valid value is built into the for expression.
Generators only support ranges, arrays, and maps.
Iterating over a Range
The range type represents a series of integers; for example, 0..3, and Min..Max.
The start of the range is the first value in the expression — for example 0 — and the end of the range is the value following .. in the expression — for example, 3. The range contains all the integers between, and including, the start and end values. For example, the range expression 0..3 contains the numbers 0, 1, 2, and 3.
Range expressions only support int values, and can only be used in for, sync, race, and rush expressions.
for (Number := 0 .. 3):
Log("{Number}")The result will add four lines to the log containing the numbers 0, 1, 2, and 3.
A for expression can return the results from each iteration in an array. In the following example, Numbers is an immutable array with the int values -1 to -10.
Numbers := for (Number := 1..10):
-NumberIterating over an Array or a Map
Iterations over arrays and maps can be just the values, or the key-value pair for maps and the index-value pair for arrays.
In this case, only the values of the array are used, and Values is an immutable array with the int values 2, 3, and 5.
Values := for (X : array{1, 2, 4}):
X+1The same can be done with a map, and Values is, in this case, an immutable array with the int values 3,7.
Values := for (X := map{ 1=>3, 0=>7 }):
XThe X->Y pattern can be used to deconstruct an index-value or key-value pair. The index (or key) is bound to the left part (X) and the value is bound to to the right part (Y).
An example of Index-value pairs from an array, Values is an immutable array with the int values 1, 3, and 6.
Values := for ( X -> Y : array{1, 2, 4}) :
X + YAn example of Index-value pairs from a map, Values is an immutable array with the int values 4, and 7.
Values := for ( X->Y := map{ 1=>3, 0=>7 }):
X + YFilter
You can add failable expressions to the for expression to filter out values from the generator. If the filter fails, then there's no result for that iteration, and for skips to the next value produced by the generator.
For example, the filter Num <> 0 is added to the for expression to exclude 0 from the returned results.
NoZero := for (Number := -5..5, Number <> 0):
NumberSyntactically, this is the same as:
expression0
for (Item : Collection, test-arg-block):
expression1
expression2Definition
You can also add named expressions to the iteration specification, and the name can be used in both the iteration specification and the body.
Values := for ( X := 1..5; Y:=SomeFunction(X); Y < 10):
YResult: an array with at most 5 items where all values are less than 10.
Nested For
You can nest a for loop inside another for loop. There are two ways to do this:
Single For Expression: Specified by multiple generators. The result is a one-dimensional array.
Multiple For Expressions: Separate
forblocks. The result is a multidimensional array.
The sections below describe these further.
Single For Expression
You can have multiple loops in a single for expression by adding more generators. The result of a single for expression with multiple generators is a one-dimensional array.
In this example, Values is an immutable array with the int values 13, 14, 23 and 24.
Values := for(X:=1..2, Y:=3..4):
X * 10 + YSemantically, this is the same as:
expression0
for (Item : Collection, Item2 : Collection2):
expression1
expression2Multiple For Expressions
You can also nest a for expression in another for-loop body. Since one for expression returns a one-dimensional array, nesting a for expression returns a two-dimensional array.
In this case, Values is an immutable array with two immutable int arrays. The first array contains the values 13, and 14, and the second array contains 23 and 24. This can be written as array{ array{13, 14}, array{23, 24} }.
Values := for ( X := 1..2 ):
for (Y := 3..4):
X * 10 + YFailure
If anything fails inside the iteration specification, then any changes due to that iteration will be rolled back.
for(X := 1..5; S := IncrementSomeVariable(); X < 3):
XThe result of this for expression is array{1,2}, with only two calls to IncrementSomeVariable after the evaluation of the for loop because the other calls were rolled back when the filter X < 3 failed.