[Oberon] Delegates
Stauber Sven Philipp
sven.stauber at inf.ethz.ch
Fri Oct 31 16:28:48 MET 2008
If you assign a procedure in a module scope to a procedure variable, only the entry address of this procedure needs to be stored. If you want to assign a method (procedure in object scope), this address is not sufficient since the method may depend on the current state of an particular object instance. Therefore, the reference to that object instance needs to be stored in the procedure variable, too.
TYPE
Procedure = PROCEDURE();
DelegateProcedure = PROCEDURE {DELEGATE} (...);
VAR
p : Procedure;
dp : DelegateProcedure;
In the above example, you can assign procedures to p but not methods, since p is a procedure variable that only stores the procedure entry point. If a procedure variable has the type PROCEDURE {DELEGATE} ..., you can also assign methods to it. Behind the scenes, both the procedure entry point and the reference to the object instance it is bound to are stored in dp.
Best,
Sven Stauber
Von: oberon-bounces at lists.inf.ethz.ch [mailto:oberon-bounces at lists.inf.ethz.ch] Im Auftrag von Søren Renner
Gesendet: Freitag, 31. Oktober 2008 15:27
An: oberon at lists.inf.ethz.ch
Betreff: [Oberon] Re: Oberon Digest, Vol 61, Issue 16
What's this {DELEGATE} syntax? What does that do?
On Fri, Oct 31, 2008 at 6:00 AM, <oberon-request at lists.inf.ethz.ch> wrote:
Send Oberon mailing list submissions to
oberon at lists.inf.ethz.ch
To subscribe or unsubscribe via the World Wide Web, visit
https://lists.inf.ethz.ch/mailman/listinfo/oberon
or, via email, send a message with subject or body 'help' to
oberon-request at lists.inf.ethz.ch
You can reach the person managing the list at
oberon-owner at lists.inf.ethz.ch
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Oberon digest..."
Today's Topics:
1. Re: Oberon and closures (Aubrey.McIntosh at Alumni.UTexas.Net)
2. Re: Oberon and closures (Alexander Iljin)
3. Re: Oberon and closures (B. Smith-Mannschott)
4. Re: Oberon and closures (B. Smith-Mannschott)
5. Re: Oberon and closures (Thomas Frey)
----------------------------------------------------------------------
Message: 1
Date: Thu, 30 Oct 2008 10:02:50 -0500
From: Aubrey.McIntosh at Alumni.UTexas.Net
Subject: Re: [Oberon] Oberon and closures
To: "ETH Oberon and related systems" <oberon at lists.inf.ethz.ch>
Message-ID:
<6d278c720810300802ia8c47e0s2e2576523d1ff990 at mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
I thing I read that procedure variables are being depreciated because
the literature finds some problem with them. I forget what the
problem is. Also, I haven't any clue what a "closure" is other than
this discussion, so I would appreciate any pointer to info that may be
more focused than my own Google search.
Anyway, I tried to modify the example a bit more so that it used type
bound procedures, not procedure variables. Here is the version for
Component Pascal.
MODULE PrivClosureExample;
(* my oberon is also a little rusty *)
TYPE
Printer = POINTER TO Closure;
Closure = RECORD
n-: INTEGER;
END;
VAR p, q: Printer;
PROCEDURE (this:Printer) Print, NEW;
END Print;
PROCEDURE CreatePrinter*(i: INTEGER): Printer;
VAR s: Printer;
BEGIN
NEW(s); s.n :=i; RETURN s
END CreatePrinter;
BEGIN
p:=CreatePrinter(2);
q:=CreatePrinter(3);
p.Print;
q.Print
END PrivClosureExample.
On Thu, Oct 30, 2008 at 3:25 AM, Jörg Straube <joerg.straube at iaeth.ch> wrote:
>
>>> From Wikipedia we find
>>> As a consequence, closures can be used to hide state,
>>> and thus to implement object-oriented programming
>
> As Oberon is object-oriented, we don't need the concept
> of "closures" to implement OOP.
>
> Joerg
>
>
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
> https://lists.inf.ethz.ch/mailman/listinfo/oberon
>
--
--
Aubrey McIntosh, Ph.D.
1502 Devon Circle
Austin TX 78723-1814
http://home.grandecom.net/~amcintosh/aubrey/Search/ <http://home.grandecom.net/%7Eamcintosh/aubrey/Search/>
------------------------------
Message: 2
Date: Thu, 30 Oct 2008 21:11:05 +0600
From: "Alexander Iljin" <ajsoft.gm at gmail.com>
Subject: Re: [Oberon] Oberon and closures
To: "ETH Oberon and related systems" <oberon at lists.inf.ethz.ch>
Message-ID:
<950bc9920810300811g1f930c2frc7227bd64c1bf01c at mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Hello!
On 10/30/08, Aubrey.McIntosh at alumni.utexas.net
<Aubrey.McIntosh at alumni.utexas.net> wrote:
> I would appreciate any pointer to info that may be
> more focused than my own Google search.
http://en.wikipedia.org/wiki/Closure_(computer_science) <http://en.wikipedia.org/wiki/Closure_%28computer_science%29>
------------------------------
Message: 3
Date: Thu, 30 Oct 2008 17:54:24 +0100
From: "B. Smith-Mannschott" <benpsm at gmail.com>
Subject: Re: [Oberon] Oberon and closures
To: ETH Oberon and related systems <oberon at lists.inf.ethz.ch>
Message-ID: <9014DD6E-0B81-4246-9021-D52AF8A7291E at gmail.com>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed; delsp=yes
On Oct 30, 2008, at 09:11, Jörg Straube wrote:
>
> What about this?
>
> MODULE Example;
> (* my oberon is also a little rusty *)
> TYPE
> Printer = POINTER TO Closure;
> Closure = RECORD
> n-: INTEGER;
> Print: PROCEDURE();
> END;
> PROCEDURE CreatePrinter*(i: INTEGER): Printer;
> VAR s: Printer;
> BEGIN
> NEW(s); s.n :=i; RETURN Printer
> END
>
> VAR p, q: Printer;
> BEGIN
> p:=CreatePrinter(2);
> q:=CreatePrinter(3);
> p.Print
> q.Print
> END Example.
>
>
> Joerg
Indeed, there is an equivalence between objects (state with behavior)
and
closures (behavior with state).
Anton van Straaten observed a few years ago (more humorously than I
could manage):
<http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html
>
The venerable master Qc Na was walking with his student, Anton.
Hoping to
prompt the master into a discussion, Anton said "Master, I have heard
that
objects are a very good thing - is this true?" Qc Na looked pityingly
at
his student and replied, "Foolish pupil - objects are merely a poor
man's
closures."
Chastised, Anton took his leave from his master and returned to his
cell,
intent on studying closures. He carefully read the entire "Lambda: The
Ultimate..." series of papers and its cousins, and implemented a small
Scheme interpreter with a closure-based object system. He learned
much, and
looked forward to informing his master of his progress.
On his next walk with Qc Na, Anton attempted to impress his master by
saying "Master, I have diligently studied the matter, and now understand
that objects are truly a poor man's closures." Qc Na responded by
hitting
Anton with his stick, saying "When will you learn? Closures are a poor
man's
object." At that moment, Anton became enlightened.
// Ben
------------------------------
Message: 4
Date: Thu, 30 Oct 2008 18:00:28 +0100
From: "B. Smith-Mannschott" <benpsm at gmail.com>
Subject: Re: [Oberon] Oberon and closures
To: ETH Oberon and related systems <oberon at lists.inf.ethz.ch>
Message-ID: <7E838A5B-F59A-4033-A414-E59C97CC60C7 at gmail.com>
Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes
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
------------------------------
Message: 5
Date: Thu, 30 Oct 2008 20:58:26 +0100
From: Thomas Frey <thomas.frey at alumni.ethz.ch>
Subject: Re: [Oberon] Oberon and closures
To: ETH Oberon and related systems <oberon at lists.inf.ethz.ch>
Message-ID: <490A11E2.1070508 at alumni.ethz.ch>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
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
>
------------------------------
--
Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
https://lists.inf.ethz.ch/mailman/listinfo/oberon
End of Oberon Digest, Vol 61, Issue 16
**************************************
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.inf.ethz.ch/pipermail/oberon/attachments/20081031/1e435196/attachment.html
More information about the Oberon
mailing list