Subsections

Program repetition

Having investigated the construction and use of multiple values, it is now time to address repetition of program actions. For example, suppose you wanted to output 8 blank lines. You could write

   print((newline,newline,newline,newline,
          newline,newline,newline,newline))

A simpler way would be to write

   TO 8 DO print(newline) OD

The integer following the TO can be any unit yielding an integer (not necessarily positive) in a meek context. If the value yielded is zero or negative, then the ensuing clause enclosed by DO and OD will not be elaborated at all. The TO ... OD construct is called a loop clause or, more simply, a loop.

If you omit the TO integer construct, the loop will be repeated indefinitely. In that case, you would need some way of terminating the program inside the loop.

A more useful form of the loop clause is shown by the following example

   FOR i TO 10
   DO
      print((i,newline))
   OD

The i is an identifier, whose declaration occurs at that point and whose mode is INT. The example will print the numbers 1 to 10, each on its own line. The range of i is the whole of the loop clause, but does not include the unit following TO. Any identifier may be used in place of i. When the TO part is omitted, it is as though TO ∞ had been written.

It is possible to modify the number of times the loop is obeyed. The simplest way is to define the starting point using the FROM construct. Here is an example:

   FOR n FROM -10 TO 10 DO print((n,blank)) OD

This prints the numbers from -10 to +10 on the screen. The integer after FROM can be any unit which yields a value of mode INT in a meek context. When FROM is omitted, it is assumed that the first value of the identifier following FOR is 1.

This example prints the square of each of the numbers from 0.2 to 0.9:

   FOR number FROM 2 TO 9
   DO
      REAL value = number / 10;
      print((value," squared =",
             value * value,newline))

In these examples, the value of the identifier has always increased by 1. The increase can be changed using the BY construct. For example, to print the cubes of the even numbers between 30 and 50 inclusive, you could write4.4

   FOR n FROM 30 BY --2 TO 50
   DO
      print((n**3,newline))
   OD

The BY construct is particularly useful for decreasing the value of the identifier:

   []CHAR title =
          "Programming Algol 68 Made Easy";

   FOR c FROM UPB title BY -1 TO LWB title
   DO
      print(title[c])
   OD

This last example shows how useful the loop clause can be for accessing some of or all of the elements of a multiple. Here is another example:

   []INT hh=(7,17,27,37,47);
   INT two=2;

   FOR i BY --2 TO UPB hh
   DO
      print(hh[i] * hh[i])
   OD

which will print

        +49        +729       +2209

on one line. Omitting the BY construct assumes a default step of 1.

Notice how use of the LWB and UPB operators ensures that your program does not try to use a subscript outwith the bounds of the multiple. If you try to access an element whose subscript is greater than the upper bound (or less than the lower bound), the program will fail at run-time with an appropriate error message.

An important use of the identity declaration is that of optimisation. In the previous example, the computation of the ith element of hh takes a little time, and there is no point in repeating it. In the following example, the identity declaration computes the value of hh[i] and the print statement uses the resulting value twice:

   FOR i BY --2 TO UPB hh
   DO
      INT hhi = hh[i];
      print((hhi * hhi,newline))
   OD

Everything said about multiples with elements of mode INT or CHAR applies equally well to multiples whose elements have mode REAL. A FOR loop yields no value (cf section 6.1.5).


Exercises

3.11
Write an Algol 68 program which will print the cubes of the numbers from 1 to 25. Ans[*]
3.12
Write a program which will print the characters of the alphabet backwards, all on one line. Ans[*]


Sian Mountbatten 2012-01-19