[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