[comp.object] What are closures?

pkr@media01.UUCP (Peter Kriens) (03/13/91)

I have been following the discussion about the "Emperor strikes back"
for quite some time now. The word closures is used many times
and normally I am able to understand what is meant from the context.But
in this case I have been confoundly confused. Could anybody give
a short description of it? It wasn't in my dictionary...

Peter Kriens
pkr@media01.uucp

pcg@test.aber.ac.uk (Piercarlo Antonio Grandi) (03/13/91)

On 12 Mar 91 21:35:02 GMT, pkr@media01.UUCP (Peter Kriens) said:

pkr> The word closures is used many times and normally I am able to
pkr> understand what is meant from the context. But in this case I have
pkr> been confoundly confused.

Strictly speaking, a closure is a persistent reusable denotable "first
class" context.

In many languages contexts (aka environemt frames) are not denotable or
persistent or reusable; each procedure instance creates a new implicit
context for that invocation.

Closure is at times used by extension to indicate the whole of a
persistent reusable denotable procedure instance, but while accepting
the convention I would like to insist that more properly it is only the
context therein.

In the debate you have been following some have insisted (me, for
example :->) that an object in most OO languages is a persistent
denotable reusable lexical context shared by all the methods for that
object.
--
Piercarlo Grandi                   | ARPA: pcg%uk.ac.aber@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@aber.ac.uk

johnson@cs.uiuc.EDU (Ralph Johnson) (03/15/91)

Piercarlo says:

|> Strictly speaking, a closure is a persistent reusable denotable "first
|> class" context.
|> 
|> In many languages contexts (aka environemt frames) are not denotable or
|> persistent or reusable; each procedure instance creates a new implicit
|> context for that invocation.
|> 
|> Closure is at times used by extension to indicate the whole of a
|> persistent reusable denotable procedure instance, but while accepting
|> the convention I would like to insist that more properly it is only the
|> context therein.
|> 
|> In the debate you have been following some have insisted (me, for
|> example :->) that an object in most OO languages is a persistent
|> denotable reusable lexical context shared by all the methods for that
|> object.

This certainly explains our confusion.  We have different definitions
of closure.  Piercarlo says that a closure is a context.  I have always
been told that it was a procedure bound with a context.  There is a big
difference.  The difference is that the only operation on a closure is
to evaluate it, while a context acts like a dictionary, i.e. you can
look up the values of symbols bound in it and change them.

You can implement objects with closures (i.e. as a procedure bound
to a context).  Scheme programmers do it all the time.  However, this
is not the normal way to think of an object.  On the other hand, an
object is obviously a context.  Thus, my argument with Piercarlo
was caused by his nonstandard use of the word "closure".

Contexts are records.  Closures are procedure-like thingees with
a private state.  Contexts are simple to understand.  Closures are
complicated.   (This isn't really fair, but I am on a roll!)
Claiming that objects are contexts is no big deal, while claiming
that they are closures certainly is.

By the way, Smalltalk has both contexts and closures.  In fact, it has
many kinds of contexts.  Each object is a context, of course.  There
is a class "MethodContext" that represents stack frames.  Further,
Dictionary is a kind of context that is used by application programs.
Smalltalk blocks are closures (well, the truth is a little more
complicated).  If you take a Self-like view of the world, even methods
are closures.

However, objects ARE NOT closures.

Ralph Johnson -- University of Illinois at Urbana-Champaign

pcg@test.aber.ac.uk (Piercarlo Antonio Grandi) (03/16/91)

In article <1991Mar14.161424.5659@m.cs.uiuc.edu> johnson@cs.uiuc.EDU
(Ralph Johnson) writes:

johnson> Piercarlo says:

pcg> Strictly speaking, a closure is a persistent reusable denotable
pcg> "first class" context. [ ... ] Closure is at times used by
pcg> extension to indicate the whole of a persistent reusable denotable
pcg> procedure instance, but while accepting the convention I would like
pcg> to insist that more properly it is only the context therein.

The reason is that there is already a name for closure+procedure bound
in it, and it is that 'procedure instance', or maybe 'partially applied
procedure'. Neither is the same as 'continuation' or 'suspended
procedure instance'.

johnson> This certainly explains our confusion.  We have different
johnson> definitions of closure.  Piercarlo says that a closure is a
johnson> context.  I have always been told that it was a procedure bound
johnson> with a context.  There is a big difference.  The difference is
johnson> that the only operation on a closure is to evaluate it,

This is surely a very limited view of a closure, even in the extended
sense you prefer. Consider POP-2, where you can also freeze new
arguments. The same when currying in ML. Consider also the little known
SL5.

johnson> while a context acts like a dictionary, i.e. you can look up
johnson> the values of symbols bound in it and change them.

Also, in several Lisps (Interlisp, if memory serves me well, for
example) you *can* access the closure part of an instantiated procedure
and change the values of the closed variables without running the bound
procedure (this is essential, for example, to implement debuggers and
inspectors).

johnson> You can implement objects with closures (i.e. as a procedure
johnson> bound to a context).  Scheme programmers do it all the time.
johnson> However, this is not the normal way to think of an object.

Again, too bad. I still cannot see how the three examples I have posted,
in Scheme, in C++ and in Simula 67 are different but in syntax. They all
have objects that are closures, that is a context over which all the
methods in the relevant class are closed, even if this is only manifest
in the Scheme example.

johnson> On the other hand, an object is obviously a context.  Thus, my
johnson> argument with Piercarlo was caused by his nonstandard use of
johnson> the word "closure".

I actually think that I am using closure properly. Even under the use of
closure by extension as a denotable context + a bound procedure, objects
are closures:

pcg> In the debate you have been following some have insisted (me, for
pcg> example :->) that an object in most OO languages is a persistent
pcg> denotable reusable lexical context shared by all the methods for
pcg> that object.

johnson> Contexts are records.  Closures are procedure-like thingees
johnson> with a private state.  Contexts are simple to understand.
johnson> Closures are complicated.  (This isn't really fair, but I am on
johnson> a roll!)  Claiming that objects are contexts is no big deal,
johnson> while claiming that they are closures certainly is.

I am really thinking now that you are confusing objects with their state
(which is a record), and maybe you also mistakenly feel that I confuse
closures with continuations.

You admit that objects are contexts. OK. Now is there any procedure
bound within that context? In most OO languages, yes, all the methods
that define the behaviour of that object. More precisely, as the Scheme
example clearly shows, the procedure bound in the context which is the
state of the object is the *method dispatcher* itself, and this is true
in all non actor languages, even if the method dispatcher is not
manifest.

Smalltalk included. In classic Smalltalk implementations, I will not
tire to repeat it, the pointer from the object to the class object and
thus method dictionary is the static link of the method dispatcher
closure.

So really the state or *data* part of an object is the context part of
what you call a closure.  But the object is not just its data part, it
is also its behaviour. Or else we have very different ideas of what
traditional OO programming is all about.

Therefore, even accepting your terminology, objects *are* closures (just
as well as their _state_ is the context of the closure), unless _state_
and _object_ are (incorrectly) made synonymous.

Note that I never claimed that objects are closures in the sense of
being a context plus a _continuation_. Maybe you are not noting the
distinction between procedure and continuation; in any case I would
surely object to defining object as a context plus a continuation,
except in the actor view of objects.

Please note that while in both Scheme and Simula 67 one can implement
objects both as closures and as continuations, my examples were all for
the closure case, which is exactly isomorph to any Smalltalk implementation.
--
Piercarlo Grandi                   | ARPA: pcg%uk.ac.aber@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@aber.ac.uk

pkr@media01.UUCP (Peter Kriens) (03/18/91)

I would like to thank everybody on the net that replied to my
questions about the definition for closure. I thought I was the
only one that was confused.

I now realize that I was in large group.

Thanks
Peter Kriens					pkr@media01