[Oberon] Intermediate scopes in Oberon-07
August Karlstrom
fusionfile at gmail.com
Sat Feb 10 16:26:35 CET 2018
On 2018-02-10 12:35, Chris Burrows wrote:
> I can't think of any genuine use for an intermediate TYPE if intermediate variables of that type are inaccessible.
Or the types themselves (see below).
> Can you refer me to an existing real-world practical Oberon example where an intermediate type is accessed in a nested procedure?
Let's say we have a generic list data type which exports an abstract
element type which can be extended in a client module. Suppose it also
defines an Apply procedure which receives a procedure and an accumulator
and applies the procedure on each element in the list and updates the
accumulator:
MODULE Lists;
TYPE
Element* = POINTER TO RECORD END;
List* = POINTER TO RECORD
...
END;
Accumulator* = RECORD END;
Applicator* = PROCEDURE (x: Element; VAR acc: Accumulator);
...
PROCEDURE Apply*(f: Applicator; t: List; acc: Accumulator);
...
END Apply;
END Lists.
A procedure P in a client module may make use of List and Apply to
implement an algorithm. Let's say that the list contains integers and
that the applicator is a simple Add procedure:
PROCEDURE P;
TYPE
IntegerElem = POINTER TO RECORD (Lists.Element) i: INTEGER END;
IntegerAcc = RECORD (Lists.Accumulator) i: INTEGER END;
VAR
list: Lists.List;
sum: IntegerAcc;
PROCEDURE Add(x: Lists.Element; VAR sum: Lists.Accumulator);
BEGIN
INC(sum(IntegerAcc).i, x(IntegerElem).i)
END Add;
BEGIN
...
sum.i := 0;
Lists.Apply(Add, list, sum);
...
END P
The procedure P is not valid since IntegerElem and IntegerAcc cannot be
accessed from the Add procedure. Therefore they have to be declared
globally. This breaks the rule that each identifier should have the
smallest possible scope.
-- August
More information about the Oberon
mailing list