[Oberon] Unneeded restrictions on local procedures
August Karlstrom
fusionfile at gmail.com
Thu Dec 21 21:02:09 CET 2023
On 2023-12-20 23:39, Joerg wrote:
> If I understood August correctly, his idea was to get rid of restrictions not invent new ones.
> We could indeed tell the compiler to allow assigments only to local procedure variables, but I think this restriction is not needed.
When using higher order procedures it would be natural to pass locally
declared (often small) procedures. In the following example the
procedures Init, Print, Odd and Sum would be more naturally declared as
local procedures in Test.
MODULE test;
IMPORT Out;
TYPE
Selector = PROCEDURE (x: INTEGER): BOOLEAN;
Applicator = PROCEDURE (i: INTEGER; VAR x: INTEGER);
Reducer = PROCEDURE (acc, x: INTEGER): INTEGER;
PROCEDURE Filter(wanted: Selector; VAR a: ARRAY OF INTEGER; VAR n:
INTEGER);
VAR i, j: INTEGER;
BEGIN
j := 0;
FOR i := 0 TO n - 1 DO
IF wanted(a[i]) THEN
a[j] := a[i];
INC(j)
END
END;
n := j
END Filter;
PROCEDURE Apply(f: Applicator; VAR a: ARRAY OF INTEGER; n: INTEGER);
VAR i: INTEGER;
BEGIN
FOR i := 0 TO n - 1 DO
f(i, a[i])
END
END Apply;
PROCEDURE Reduction(f: Reducer; acc: INTEGER; a: ARRAY OF INTEGER;
n: INTEGER): INTEGER;
VAR i: INTEGER;
BEGIN
FOR i := 0 TO n - 1 DO
acc := f(acc, a[i])
END
RETURN acc
END Reduction;
PROCEDURE Init(i: INTEGER; VAR x: INTEGER); (*should be local to Test*)
BEGIN
x := i + 1
END Init;
PROCEDURE Print(i: INTEGER; VAR x: INTEGER); (*should be local to Test*)
BEGIN
Out.Int(x, 0);
Out.Char(" ")
END Print;
PROCEDURE Odd(x: INTEGER): BOOLEAN; (*should be local to Test*)
RETURN ODD(x)
END Odd;
PROCEDURE Sum(acc, x: INTEGER): INTEGER; (*should be local to Test*)
RETURN acc + x
END Sum;
PROCEDURE Test;
VAR a: ARRAY 10 OF INTEGER;
n, s: INTEGER;
BEGIN
Apply(Init, a, LEN(a));
n := LEN(a);
Filter(Odd, a, n);
Apply(Print, a, n);
Out.Ln;
s := Reduction(Sum, 0, a, n);
Out.Int(s, 0);
Out.Ln
END Test;
BEGIN
Test
END test.
More information about the Oberon
mailing list