[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