REDUCE

5.4 FOR Statements

The for statement is used to define a variety of program loops. Its general syntax is as follows: \[ \texttt {for}\ \left \{ \begin {array}{@{}c@{}} \langle \textit {var}\rangle \ \texttt {:=}\ \langle \textit {number}\rangle \ \left \{ \begin {array}{@{}c@{}} \texttt {step}\ \langle \textit {number}\rangle \ \texttt {until} \\ \texttt {:} \end {array} \right \}\ \langle \textit {number}\rangle \\[3mm] \texttt {each}\ \langle \textit {var}\rangle \ \left \{ \begin {array}{@{}c@{}} \texttt {in} \\ \texttt {on} \end {array} \right \}\ \langle \textit {list}\rangle \end {array} \right \}\ \langle \textit {action}\rangle \ \langle \textit {exprn}\rangle \] where

\(\langle \)action\(\rangle \) \(\longrightarrow \) do\(\ \mid \ \)product\(\ \mid \ \)sum\(\ \mid \ \)collect\(\ \mid \ \)join.

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 \(\langle \)exprn\(\rangle \) 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 \(\langle \)exprn\(\rangle \) each time are linked together to make a list, and join means that the values of \(\langle \)exprn\(\rangle \) 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 \(\langle \)exprn\(\rangle \).

In all cases, \(\langle \)exprn\(\rangle \) is evaluated algebraically within the scope of the current value of \(\langle \)var\(\rangle \). If \(\langle \)action\(\rangle \) is do, then nothing else happens. In other cases, \(\langle \)action\(\rangle \) 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 sum1 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 \(\langle \)list\(\rangle \) is empty in the for each case, \(\langle \)exprn\(\rangle \) is not evaluated at all.

Examples:

1.
If a, b have been declared to be arrays, the following stores \(5^{2}\) through \(10^{2}\) 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 \(i^{2} = -1\). Furthermore, in algebraic mode, the value of the control variable is substituted in \(\langle \)exprn\(\rangle \) 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.


Hosted by Download REDUCE Powered by MathJax