[Oberon] Oberon and closures
B. Smith-Mannschott
benpsm at gmail.com
Thu Oct 30 07:51:51 MET 2008
On Oct 29, 2008, at 05:38, Douglas G. Danforth wrote:
> Martin Bishop wrote:
>> Is it possible to create a closure in Oberon? If not, why not? what
>> prevent it?
>> --
>> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related
>> systems
>> https://lists.inf.ethz.ch/mailman/listinfo/oberon
>>
> From Wikipedia we find
>
> "
>
> In computer science <http://en.wikipedia.org/wiki/Computer_science>,
> a *closure* is a function <http://en.wikipedia.org/wiki/Function_%28programming%29
> > that is evaluated in an environment containing one or more bound
> variables <http://en.wikipedia.org/wiki/Bound_variable>. When
> called, the function can access these variables. The explicit use of
> closures is associated with functional programming <http://en.wikipedia.org/wiki/Functional_programming
> > and with languages such as ML <http://en.wikipedia.org/wiki/ML_programming_language
> > and Lisp <http://en.wikipedia.org/wiki/Lisp_%28programming_language%29
> >. Constructs such as objects <http://en.wikipedia.org/wiki/Object_oriented_programming
> > in other languages can also be modeled with closures.
>
> In some languages, a closure may occur when a function is defined
> within another function, and the inner function refers to local
> variables of the outer function. At runtime <http://en.wikipedia.org/wiki/Runtime
> >, when the outer function executes, a closure is formed, consisting
> of the inner function’s code and references to any variables of the
> outer function required by the closure.
>
> A closure can be used to associate a function with a set of
> "private" variables, which persist over several invocations of the
> function. The scope <http://en.wikipedia.org/wiki/Scope_%28programming%29
> > of the variable encompasses only the closed-over function, so it
> cannot be accessed from other program code. However, the variable is
> of indefinite extent <http://en.wikipedia.org/wiki/Variable#Scope_and_extent
> >, so a value established in one invocation remains available in the
> next. As a consequence, closures can be used to hide state <http://en.wikipedia.org/wiki/Information_hiding
> >, and thus to implement object-oriented programming <http://en.wikipedia.org/wiki/Object-oriented_programming
> >.
>
> "
> Global variables in an Oberon module act like the bound variables
> for every procedure of the module that accesses those variables.
> Oberon-2 and Component Pascal allow for functions within functions
> and so the above hold for the local variables in the outer
> procedure.
>
> 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).
// ben
More information about the Oberon
mailing list