Article View: comp.lang.oberon
Article #825Re: Why doesn't Oberon have proper procedure values?
From: Mark Hamburg
Date: Tue, 23 Jan 1996 16:42
Date: Tue, 23 Jan 1996 16:42
82 lines
3703 bytes
3703 bytes
In article <1996Jan22.125737.5658@zermelo.comlab.ox.ac.uk>,
mike@comlab.ox.ac.uk (Mike Spivey) wrote:
> Oberon allows procedures to be passed as arguments of other
> procedures, and to be stored as components of records: in fact, this
> is the basis of Oberon's use in object-oriented programming. But
> there seems to be a language restriction that prohibits the use of
> local procedures in this way -- and it seems to me that this resticts
> the usefulness of the language in a serious way.
>
> For example, we can define collections that support iterator methods,
> but these methods would be more useful if their arguments could be
> local procedures. To give a trivial example:
>
> PROCEDURE sum(xs: intset);
> VAR s: integer;
>
> PROCEDURE add(x: integer);
> BEGIN s := s + x END add;
>
> BEGIN
> s := 0;
> xs.do(add);
> RETURN s
> END sum;
>
> (sorry about the syntax). This procedure sums a set of integers by
> calling the iterator 'do', passing a local procedure that adds each
> number to the local variable 's'. Without local procedures as
> parameters, 's' would have to be made a global variable -- Yuk!
>
> Is there any good reason why Oberon doesn't allow this? I don't seem
> to have any serious difficulty in implementing it!
>
> -- Mike Spivey
This isn't supported because you get into an interesting problem if xs.do
were to store its parameter into a global variable which we later called
through. If that happens, the stack frame for sum needs to survive for an
indefinite period of time. The programming language Scheme relies heavily
on support for such "closures" -- see Abelson and Sussman's Structure and
Interpretation of Computer Programs.
You can make this sort of thing work if you introduce into the language the
notion of types that can only be passed in parameters but can't be stored
to global variables or the heap. Moessenboeck combined this restriction
with a notation for anonymous local procedures in a proposed Oberon
extension called blocks in a SIGPLAN paper a few years ago.
I've actually been working with an Oberon-like language that we extended to
include an expanded version of blocks, and they have proven very useful for
describing protocols. For example:
PROCEDURE WithOpenFileDo(fileRef: FileRef;
action: BLOCK(openFile: OpenFile));
VAR myOpenFile: OpenFile;
BEGIN
myOpenFile := Open(fileRef);
action(myOpenFile);
Close(myOpenFile)
END WithOpenFileDo;
This procedure encapsulates all of the knowledge about opening and closing
files. Now, we can just write our read code as follows:
PROCEDURE ReadBazFile(fileRef: FileRef): Baz;
VAR theBaz: Baz;
BEGIN
WithOpenFileDo(fileRef,
BLOCK(openFile: OpenFile)
... use openFile to extract data from the file
and build theBaz ...
END);
RETURN theBaz
END ReadBazFile;
You can imagine a version that encapsulates the process of picking the file
to read. You could even build this on top of WithOpenFileDo since blocks
can be passed from one procedure to another, they just can't escape from
being a parameter.
Mark
Technical Details
Message-ID:
<mhamburg-230196084236@macb302.mv.us.adobe.com>Path:
arc1-ca.pugleaf.net!macb302.mv.us.adobe.com!userReferences:
<1996Jan22.125737.5658@zermelo.comlab.ox.ac.uk>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!macb302.mv.us.adobe.com!user From: mhamburg@mv.us.adobe.com (Mark Hamburg) Newsgroups: comp.lang.oberon Subject: Re: Why doesn't Oberon have proper procedure values? Followup-To: comp.lang.oberon Date: Tue, 23 Jan 1996 08:42:36 -0800 Organization: Adobe Systems, Inc. Message-ID: <mhamburg-230196084236@macb302.mv.us.adobe.com> References: <1996Jan22.125737.5658@zermelo.comlab.ox.ac.uk> NNTP-Posting-Host: macb302.mv.us.adobe.com