Iterating with 'loop'

A loop block repeats a block of Envision code. The number of iterations is passed as an integer after the loop keyword. The value of the integer must be between 2 and 10 (inclusive). The following script illustrates the loop block:

a = 1
loop 3
  // (a, b) is (4,   2) after the 1st iteration,
  //           (10,  5) after the 2nd iteration,
  //           (22, 11) after the 3rd iteration 
  b = a + 1 
  a = 2 * b
show summary "" with a, b // 22, 11

Advanced remark: The loop is similar to a strongly-typed code macro-expansion. Under the hood, the Envision code is treated as if it had been copy-pasted that many times. This explain why Lokad sets a low limit at 10.

Unlike most blocks in Envision, a loop block does not involve any scoping. Hence, in the script above, the variable b remains accessible after exiting the loop block.

This script could have been equivalently written:

a = 1

b = a + 1 // 1st iteration
a = 2 * b
b = a + 1 // 2nd iteration
a = 2 * b
b = a + 1 // 3rd iteration
a = 2 * b

show summary "" with a, b // 22, 11

Constant iteration count

The loop iteration count does not need to be a literal, it can be any constant expression (although it will report an error if the constant value is less than 1 or more than 10):

const iteration = 1 + today() - monday(today())
const day = "Sunday"
loop iteration
  day = match day 
    "Sunday"    -> "Monday"
    "Monday"    -> "Tuesday"
    "Tuesday"   -> "Wednesday"
    "Wednesday" -> "Thursday"
    "Thursday"  -> "Friday"
    "Friday"    -> "Saturday"
    "Saturday"  -> "Sunday"
show label "Today" with day

Iteration lists

It is also possible to loop through a list of values, using loop VAR in (EXPR, EXPR) syntax:

All = ""
loop Letter in ("A", "B", "C", "D")
  All = "\{All}\{Letter}"

This is expanded to:

All = ""

Letter = "A"
All = "\{All}\{Letter}"

Letter = "B"
All = "\{All}\{Letter}"

Letter = "C"
All = "\{All}\{Letter}"

Letter = "D"
All = "\{All}\{Letter}"

The maximum number of values (and iterations) is still 10.

The list of values can contain arbitrary expressions (it is not limited to only literals, or even scalars).

table T = extend.range(10)
S = 0
loop T.X in (T.N, T.1, log(T.N) + 2)
  S = S + sum(T.X)

Tuples can be unpacked in the list of values. The example below behaves exactly as if if the list had been "A", "B", "C", "D".

All = ""
BC = ("B", "C")
loop Letter in ("A", ...BC, "D")
  All = "\{All}\{Letter}"

Iteration ranges

If the list of values is a range of numbers, then a shorter syntax also exists:

Sum = 0
loop N in 1 .. 5
  Sum = Sum + N

This is equivalent to:

Sum = 0
loop N in (1, 2, 3, 4, 5)
  Sum = Sum + N

Restrictions over block contents

loop blocks cannot include any import, def, show, read or write statements, nor can they include nested loop blocks.

They can include table declarations under certain conditions, as illustrated by the following example:

a = 10
b = 0
table T = extend.range(10)
loop 10
  a = a - 1
  table T = where T.N < a
  b = b + sum(T.N)
show summary "" with a, b // 0, 120

In the above script, the repeated declarations of the table T are valid because they are filters iteratively applied over the same table.

Loops can also be used inside a table comprehension:

table T = with
  [| as A |]
  loop N in 1..10
    [| N |]

show table "T" with T.A

This displays a table with a single “A” column containg the values 1 to 10.

User Contributed Notes
0 notes + add a note