REDUCE

5.4 FOR Statements

The FOR statement is used to define a variety of program loops. Its general syntax is as follows:

                     {                   }
    (|                 STEP ⟨number⟩UNTIL           )|
    |{⟨var⟩:= ⟨number⟩           :           ⟨number⟩ |}
FOR |                       {IN }                  | ⟨action⟩⟨exprn⟩
    |(              EACH ⟨var⟩  ON  ⟨list⟩             |)

where

action ::= doproductsumcollectjoin.

The assignment form of the FOR statement defines an iteration over the indicated numerical range. If expressions that do not evaluate to numbers are used in the designated places, an error will result.

The FOR EACH form of the FOR statement is designed to iterate down a list. Again, an error will occur if a list is not used.

The action DO means that exprn is simply evaluated and no value kept; the statement returning 0 in this case (or no value at the top level). COLLECT means that the results of evaluating exprn each time are linked together to make a list, and JOIN means that the values of exprn are themselves lists that are joined to make one list (similar to CONC in Lisp). Finally, PRODUCT and SUM form the respective combined value out of the values of exprn.

In all cases, exprn is evaluated algebraically within the scope of the current value of var. If action is DO, then nothing else happens. In other cases, action is a binary operator that causes a result to be built up and returned by FOR. In those cases, the loop is initialized to a default value (0 for SUM, 1 for PRODUCT, and an empty list for the other actions). The test for the end condition is made before any action is taken. As in Pascal, if the variable is out of range in the assignment case, or the list is empty in the FOR EACH case, exprn is not evaluated at all.

Examples:

  1. If A, B have been declared to be arrays, the following stores 52 through 102 in A(5) through A(10), and at the same time stores the cubes in the B array:
       for i := 5 step 1 until 10 do <<a(i):=i^2; b(i):=i^3>>

  2. As a convenience, the common construction
            STEP 1 UNTIL

    may be abbreviated to a colon. Thus, instead of the above we could write:

            for i := 5:10 do <<a(i):=i^2; b(i):=i^3>>

  3. The following sets C to the sum of the squares of 1,3,5,7,9; and D to the expression x*(x+1)*(x+2)*(x+3)*(x+4):
            c := for j:=1 step 2 until 9 sum j^2;  
            d := for k:=0 step 1 until 4 product (x+k);

  4. The following forms a list of the squares of the elements of the list {a,b,c}:
            for each x in {a,b,c} collect x^2;

  5. The following forms a list of the listed squares of the elements of the list {a,b,c} (i.e., {{A^2},{B^2},{C^2}}):
            for each x in {a,b,c} collect {x^2};

  6. The following also forms a list of the squares of the elements of the list {a,b,c}, since the JOIN operation joins the individual lists into one list:
            for each x in {a,b,c} join {x^2};

The control variable used in the FOR statement is actually a new variable, not related to the variable of the same name outside the FOR statement. In other words, executing a statement for i:=…doesn’t change the system’s assumption that i2 = -1. Furthermore, in algebraic mode, the value of the control variable is substituted in exprn only if it occurs explicitly in that expression. It will not replace a variable of the same name in the value of that expression. For example:

        b := a; for a := 1:2 do write b;

prints A twice, not 1 followed by 2.