[Oberon] EXIT statement?

Diego Sardina sardinadiego at gmail.com
Fri Aug 29 17:58:13 CEST 2014


> Hi,

Hi

> Does anyone know the reasoning behind [..] the EXIT statement?
> Why does it only work inside a LOOP statement [..]?

These forms of iteration in Oberon have a precise semantic:

In the WHILE statement the termination condition is checked each time
*before* the execution of the statement sequence.

In the REPEAT statement the termination condition is checked each time
*after* the execution of the statement sequence.

The LOOP statement can have multiple termination conditions (with EXIT)
*within* the statement sequence.

WHILE/REPEAT/FOR statements do not expect to have arbitrary exit points,
but they can have a premature RETURN (that is more evil than EXIT) in
the previous Oberon report.

> why is there no CONTINUE statement [..]?

The LOOP statement with arbitrary exit points, CONTINUE statement and
RETURN statement are forms of unstructured control flow. They are like
goto and the result is spaghetti code: harder to read and to mantain.

> Is there some inherent drawback/downside in adding this to the language?

In general an unstructured control flow is harder to optimise.

Generation of SSA form is also hard for these forms of unstructured
statement, in particular in a single-pass compiler.

A suggested reading about this:

Brandis - Single-Pass Generation of SSA Form for Structured Languages.

> I'm looking [..] if I can add a few features that [..] seem quite useful.

There is always an alternative formulation that doesn't require any of
those forms and they are often surprisingly better in look, code quality
and maintenance.

For example I converted Sets.Mod to Oberon-07. In particular the major
change was the removal of a premature return in the function procedure.

This was the original procedure:

PROCEDURE Includes*(VAR s1, s2: ARRAY OF SET): BOOLEAN;
  VAR i: INTEGER;
BEGIN
  i := 0;
  WHILE i < LEN(s1) DO
    IF s1[i] + s2[i] # s1[i] THEN RETURN FALSE END;
    INC(i)
  END;
  RETURN TRUE;
END Includes;

Without the premature return, it became:

PROCEDURE Includes*(s1, s2: ARRAY OF SET): BOOLEAN;
  VAR i: INTEGER;
BEGIN
  i := 0;
  WHILE (i < LEN(s1)) & (s1[i] + s2[i] = s1[i]) DO INC(i) END;
  RETURN i = LEN(s1);
END Subset;

The code is not only shorter than the previous one, but the termination
condition makes the result more visible from an algorithmic point of
view.

The expression (i = LEN(s1)) OR (s1[i] + s2[i] # s1[i]) is your resulting
condition after the execution of the WHILE statement and it is also the
result of your algorithm (in this case i = LEN(s1) suffice).

What is the resulting condition of the algorithm in the previous one?
It's hard to say, it's spaghetti code. Although not very visible, the
condition is the same. But just imagine a very complex algorithm in a
procedure with a lot of premature returns, it will be a challenge for
you.

It is a nightmare to postulate pre/post conditions of an algorithm
with spaghetti code.

--
Diego Sardina



More information about the Oberon mailing list