[Oberon] Oberon and closures
Thomas Frey
thomas.frey at alumni.ethz.ch
Thu Oct 30 20:58:26 MET 2008
In Active Oberon we have an additional way of simulating (strongly
typed) closures.
Concept:
the reachable state of the closure function is stored in the fields of a
local OBJECT type (POINTER TO RECORD) (Note : Bound variables in
functional languages are "read only", here we rely on the programmer)
The closure itself is then a delegate procedure variable bound to a
method of an instance of the local OBJECT (class). The delegate
encapsulates the code and the state (as a closure)
The advantage of this way of doing a "closure" is that the computational
effort is visible to the programmer and not hidden behind the scene as
in other languages. (Note : Using objects and delegates normally allows
for more natural solutions than the following example which tries to
mimic closures as closely as possible)
MODULE Closure; (** AUTHOR "tf"; PURPOSE "closure simulation"; *)
IMPORT
Out := KernelLog;
TYPE
Printer = PROCEDURE {DELEGATE} ();
(* creates a closure *)
PROCEDURE CreatePrinter(nr : LONGINT): Printer;
TYPE
(* container for the accessed scope *)
PrinterClosure = OBJECT
VAR nr : LONGINT; (* state *)
(* functionality, able to access the "copied scope"*)
PROCEDURE Print;
BEGIN
Out.Int(nr, 0); Out.Ln;
END Print;
END PrinterClosure;
VAR
closure : PrinterClosure;
BEGIN
(* create the container for the bound variables *)
NEW(closure);
(* "bind" the variables *)
closure.nr := nr;
(* return the closure *)
RETURN closure.Print;
END CreatePrinter;
PROCEDURE Test*;
VAR print : Printer;
BEGIN
print := CreatePrinter(5);
(* use the closure *)
print();
END Test;
END Closure.
Closure.Test
--Thomas
B. Smith-Mannschott schrieb:
>
> On Oct 30, 2008, at 09:16, Bob Walkden wrote:
>
>>>> So, yes, you can create a closure in Oberon.
>>>
>>> Well, no, not really. The Module being a single giant closure over
>>> all the procedures defined in it is *not* what is generally meant by
>>> "closure". In particular, languages which support closures generally
>>> allow something like this:
>>>
>>> MODULE Example;
>>> (* my oberon's a little rusty *)
>>> TYPE
>>> Printer = PROCEDURE();
>>> VAR
>>> p, q: Printer;
>>>
>>> PROCEDURE CreateNumberPrinter(n: INTEGER): Printer;
>>> PROCEDURE PrintingProcedure;
>>> BEGIN Out.WriteInt(n)
>>> END PrintingProcedure;
>>> BEGIN
>>> RETURN PrintingProcedure
>>> END CreateNumberPrinter;
>>>
>>> BEGIN
>>> p := CreateNumberPrinter(1);
>>> q := CreateNumberPrinter(2);
>>> p; (* prints 1 *)
>>> q; (* prints 2 *)
>>> END Example;
>>>
>>> Note that each invocation of CreateNumberPrinter creates a new closure
>>> over the nested procedure PrintingProcedure. In fact the fact that
>>> Pascal/Modula/Oberon only allows top-level procedures as procedure
>>> values appears to be a direct result of the fact that the language
>>> doesn't support proper closures. (In order to support closures as
>>> above you need something more involved than a simple stack as an
>>> instance of PrintingProcedure needs to find its "n", even after the
>>> CreateNumberPrinter that created it is no longer active on the stack).
>>>
>>
>> "the language doesn't support proper closures"
>>
>> What are the benefits of supporting this? It doesn't feel to me as
>> though it is
>> in 'the spirit of Oberon'. It feels like the kind of accident waiting
>> to happen
>> that Prof. Wirth preferred to avoid.
>
> Yes supporting full closures would have complicated the compiler and/or
> the runtime system considerably and wouldn't have been in Wirth's style.
> By choosing not to indulge in this feature he was able to keep his
> languages
> and compilers far smaller and simpler than they otherwise would have been.
>
> There's no law that says that every language must support closures (or
> tail call eliminiation, or mult-methods, continuations, or ...) and I for
> one am glad that Wirth chose to keep Oberon simple.
>
> // Ben
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> https://lists.inf.ethz.ch/mailman/listinfo/oberon
>
More information about the Oberon
mailing list