[Ada Information Clearinghouse]
Ada '83 Rationale, Sec 3.12: Loop Statements

"Rationale for the Design of the
Ada® Programming Language"

[Ada '83 Rationale, HTML Version]

Copyright ©1986 owned by the United States Government. All rights reserved.
Direct inquiries to the Ada Information Clearinghouse at adainfo@sw-eng.falls-church.va.us.

CHAPTER 3: Classical Programming

3.12 Loop Statements

The main form of loop statement allows conditional or unconditional exit statements to appear anywhere within the sequence of statements enclosed by the brackets loop and end loop:

loop
  READ_CHARACTER(NEXT);
  exit when NEXT = '*';
  PRINT_CHARACTER(NEXT);
end loop;

Although this form of loop is quite general, a special form also exists to single out the cases in which a continuation condition appears at the start of the loop:

while MORE_TO_DO loop
  ...
end loop;

Similarly two forms of for loop are provided to iterate over ranges either in normal (increasing) or in reverse (decreasing) order:

for COUNTER in 1 .. 10 loop                                         
-- 1 2 3  ...  9 10
  ...
end loop;

for COUNTER in reverse 1 .. 10 loop           -- 10 9 8  ...  2 1
  ...
end loop;

In both cases (unlike Pascal), the loop parameter is local to the loop (which solves the problem of its value after the loop). It is declared by the loop parameter specification of the for iteration scheme. The following two forms of loop parameter specification are equivalent:

COUNTER in 1 .. 10
COUNTER in INTEGER range 1 .. 10

A null range - that is, a range whose upper bound is less than its lower bound - specifies zero iterations. Within the sequence of statements of the loop, the loop parameter is constant and therefore protected against accidental attempts at modification.

More complicated forms of loop constructs such as the so-called Zahn's construct [Za 74] and the related construct provided in Modula were considered in this design but in the end rejected. As shown in the example below, situations for which such constructs would be used can be dealt with quite easily with the existing forms.

declare
  type CAUSE is (TOO_LOW, NORMAL, TOO_HIGH);
  STATE :  CAUSE :=  NORMAL;
begin
  for  ...  loop
    ...
    STATE :=  TOO_LOW;  exit;
    ...
    STATE :=  TOO_HIGH; exit;
    ...
    STATE :=  TOO_LOW;  exit;
    ...
  end loop;

  case STATE is
    when TOO_LOW  => ...
    when TOO_HIGH => ...
    when NORMAL   => ...
  end case;
end;

The major emphasis in the design of the loop statement has been on simplicity: loops should have an intuitive meaning and users should not have to consult a reference manual to understand their meaning. Several studies on the use of programming languages have shown that the vast majority of loops are very simple. Hence generalities such as the step expression of Algol 60 should be avoided. The redundancy provided for conditional exits is itself motivated by readability considerations: loop termination conditions should be marked very conspicuously. Thus, in the recommended paragraphing,

    exit when CONDITION;

is certainly more conspicuous than the equivalent form in which the exit statement is nested within an if statement:

if CONDITION then
  exit;
end if;

Guarded commands were also considered for this design and not retained. They have advantages for the development of program proofs. However, they are not compatible with other looping constructs with explicit exits. Hence if they had been retained it would have been to the exclusion of other forms of loop statement, a decision which seemed too drastic.


NEXTPREVIOUSUPTOCINDEX
Address any questions or comments to adainfo@sw-eng.falls-church.va.us.