Expand/Shrink

For Statement

A for statement sets up a special loop with a controlling loop variable that runs from an initial value up or down to some final value. e.g.
    for i=1 to 10 do
        ? i   -- ? is a short form for print()
    end for
    for i=10 to 20 by 3 do
        for j=20 to 10 by -2 do  -- counting down
            ? {i, j}
        end for
    end for
If the loop variable has already been declared it persists after the loop and can be inspected for a termination value, otherwise it is declared automatically and only exists until the end of the loop. In the latter case, outside of the loop the variable has no value and is not even declared.
The compiler does not allow assignment to a loop variable.
The initial value, loop limit and increment must all be integers.
If no increment is specified then +1 is assumed. The limit and increment values are established when the loop is entered, and are not affected by anything that happens during the execution of the loop. Note that p2js/JavaScript does not cope as well as desktop/Phix when step may or may not be negative, relying as it does on the presence of an explicit '-' at the start of any by clause. In such cases replicating the loop inside an if -ve/else or perhaps replacing it with a while statement is advised. See also scope of the loop variable.

An "illegal construct" error occurs if the end for statement is immediately preceded by an unconditional exit. In truth that happens because the compiler tries to "optimise away" the "end for", with disastrous consequences when it later tries to backpatch the zero iterations jump. There may be other cases, besides immediately before the end, where an unconditional exit causes grief. Obviously an unconditional exit means that the loop will never iterate, so it deserves to be removed (if always once) or replaced with an if construct (if zero or one). Occasionally it may be annoying when the compiler forces that on you but in the long run your code will thank you for it.

Compatibility Note: Euphoria allows floating point for loops, which Phix does not.
However, quite often they do not work as anticipated (in Euphoria), for example:
    NB: this is NOT supported in Phix, but showing what Euphoria does:
    for x=1.7 to 1.9 by 0.1 do ?x end for   -- prints 1.7,1.8
    for x=9.7 to 9.9 by 0.1 do ?x end for   -- prints 9.7,9.8,9.9
I have not analysed in any great detail why that specific case happens, and have no desire to replicate it.
Besides, it is trivial to use a predictable integer loop variable alongside a manually incremented/decremented atom to achieve the required effect, and that is certainly easier than at least one technique to ensure the desired number of iterations occur that I have seen more than once in Euphoria: adjusting limit by a "step/2 fudge factor", so for instance the above loops would behave more consistently (in Euphoria) if they ran to 1.95 and 9.95.

The by keyword can also be used in enum defintions.

See also: Floats Are Not Exact