There are several kinds of loop iterators. Use conditional loops to loop until a condition is either met or not met.
DO while Condition :Loop while the condition is true. DO until Condition :Loop until the condition is true.
The unconditional loop iterates until exiting with an Undo command. The Undo-If command can be used to conditionally exit. The bottom of the Loop is denoted by a dash.
DO always :Loop forever. Statement block ... :Optional statements. UNDO IF Condition :Exit the loop when the condition is met. Statement block ... :Optional statements. UNDO :Always exit the loop when reached. Statement block ... :Optional statements. - :Bottom of the loop
When nesting loop and conditional If blocks you can intermingle the ending dots and dashes so they are vertically aligned with the corresponding If or Do verb.
IF C = '@' | '#' DO while More and Value > 0 :Loop while a condition is true. Value -= 1 IF Value /\ 1 Odd += 1 . - .
The Do-Times construct allows you to iterate a fixed number of times. The type of the expression is a signed Word. The number of iterations is computed once before the first iteration and does not change even if variables in the expression are modified. The loop is skipped if the expression is 0 or negative.
DO Expression times :Loop a fixed number of times.
You can increment an iterator each loop using the iterative loop form. The Iterator variable can be an integer or floating point type. If it is undeclared it will be implicitly be declared as a Word. Integer iterator computations are performed using signed arithmetic.
DO Iterator = Begin to End :Iterateor increments over a range. Statement block ... -
Upon exiting the loop the value of the Iterator variable will be the last value used in the loop. Should the loop iterate zero times its value will be the value of the starting expression.
Adding a By clause lets you specify that the Iterator variable is incremented or decremented each loop.
DO Iterator = Begin to End by Step :Iterateor increments or decrements.
The chief issue in integer iterators is proper termination. Integer iterators can unexpectedly wrap if the maximum is near the maximum integer size. Floating point iterators can suffer from accumulated epsilon errors that can differ over multiple platforms. Gilda iterators are specified so that iterators behave consistently and as expected.
The bounds checks for iterative loops needs to be carefully defined in the language and properly implemented by the compiler. The looping notation may not express the programmer's intent, Loop iterators can improperly wrap, and the number of iterations with floating point bounds can vary between implementations. The paper "Design and Implementation of Iterative Loops" details how these problems are avoided with an efficient implementation.
Scanning a sting or array is such a common operation that loop constructs are added for convenience. In both cases the Iterator variable will be implicitly declared if need be. The Iterator variable for strings is a byte and scans the result of a string expression from beginning to end.
DO Character in String :Loop over a string of characters.
The array scan can cover a single dimension array or slice of a multidimensional array. The iterator variable is a pointer to each array element or a slice of an array.
DO @Pointer in Array :Loop over elements in an array.
With only one dimension the Iterator pointer references each element. With two dimensions it points to the one dimensional slice that is each row. Note that the Row and Element pointers will be implicitly declared for you.
DO @Row in Matrix: DO over a 2D matrix; Row = @Matrix[*, 0], PRINT`# "[" DO @Element in Row: DO over each element in the Row[*], PRINT`# Element | "= dddd"; Print a row of elements. - PRINT " ]" -
When scanning arrays you can also specify bounds and optionally to descend. Note that the By clause only allows a -1 to indicate descending order. When omiited the scan is ascending.
DO @P in Array :Ascend over the rightmost column. DO @P in Array by -1 :Descend over the rightmost column. DO @P in Array[ I, 2] to 5 :Elements [I, 2] through [I, 5] DO @P in Array[ I ] to 0 by -1 :Elements [I] down to .
The final loop construct retrieves values form a Sequence method. See the section about sequences for more details.
DO Element from Sequence( Argument, ... )
A rationale for the design of the loop constructs is described in the paper,