Loop EndLoop

The four valid loop constructions are:

loop <local> var (expr1, expr2)

endloop

                                    or

loop while expr1 test expr2

endloop

                                    or

loop for (initialize, test, modify)

endloop

                                    or

loop foreach <local> var expr1

endloop

The FISH program lines between loop and endloop are executed repeatedly until certain conditions are met.

In the first form, which uses an integer counter, var is given the value of expr1 initially, and is incremented by 1 at the end of each loop execution until it reaches the value of expr2. The local statement may optionally be used at this point to create var as a variable local to the function. Note that expr1 and expr2 (which may be arbitrary algebraic expressions) are evaluated at the start of the loop; redefinition of their component variables within the loop has no effect on the number of loop executions. var is a single integer variable; it may be used in expressions within the loop (even in functions called from within the loop, if it is a global variable), and may even be redefined. The code snippet below demonstrate basic usage of this form to sum all integers below a specified value.

define sum(n)
  local s = 0
  loop local i (1,n)
    s += i  
  endloop
  sum = s
end
[s = sum(10)]
list @s

With n=10, the end result of the sum is 55.

In the second form of the loop structure, the loop body is executed while the test condition is true; otherwise, control passes to the next line after the endloop statement. The form of test is identical to that described for the if statement. The expressions may involve floating-point variables as well as integers; the use of Boolean, strings and pointers is also permitted under the same conditions that apply to the if statement. The code snippet below demonstrate basic usage of this form to sum all even integers below a specified value.

define sum_even(n)
  local s = 0
  local i = 0
  loop while i <= n
    s += i
    i +=2
  endloop
  sum_even = s
end
[s2 = sum_even(10)]
list @s2

With n=10, the end result of the sum is 30.

The main function of the third form of the loop structure is to repeat execution of the loop body while the test condition is true, similar to the loop while form. But, in addition, the loop for construct provides specific locations to contain an initialize field and a modify field. So this loop is specially designed to perform a repetitive action with a counter which is initialized and modified on each iteration. It works in the following way:

  1. Initialization is executed. Generally it is an initial value setting for a counter variable (which can be local or global). This is executed only once.
  2. Condition is checked. If it is true, the loop continues; otherwise, the loop ends and the loop body is not executed.
  3. Loop body is executed.
  4. Finally, whatever is specified in the modify field is executed, and the loop goes back to step 2.

The code snippet below demonstrate basic usage of this form to sum all odd integers below a specified value.

define sum_odd(n)
  local s= 0
  loop for (local i=1, i <=n, i+=2)
    s += i  
  endloop
  sum_odd = s
end
[s_odd = sum_odd(10)]
list @s_odd

With n=10, the end result of the sum is 25.

The first three forms of the loop statement may be contrasted. In the first, the test is done at the end of the loop (so there will be at least one pass through the loop); in the second and third, the test is done at the start of the loop (so the loop will be bypassed if the test is false initially).

The fourth form of the loop statement is a specialized syntax to allow iterating through all objects inside a given container. In this case, expr1 must return a pointer to a list, or a container of objects. For example, all scalars in the list of user-defined scalars are returned by the data.scalar.list intrinsic. As with the first loop form, var may be preceded by the local statement to indicate that a local variable is to be created instead of a global one. var will be assigned to be a pointer to each object in the list consecutively. If var is deleted during processing of the loop, the loop will continue normally as long as var is not referenced again within the same loop after deletion. If other items in the container are deleted (for example, if a function that deletes the contents of the container is called), then the loop might exit prematurely.

Loops may be nested to any depth. Within the loop, the exit loop statement may be used to break out of the loop and continue processing after the endloop statement. In addition, the continue statement may be used to stop processing the current iteration and continue to the next iteration.