From: pcg@aber.ac.uk (Piercarlo Grandi)
Newsgroups: comp.object
Subject: Procedures and their instances (objects in traditional OO languages)
Date: 27 Jan 93 16:04:20 GMT
	<1993Jan15.033713.27130@netcom.com> <PCG.93Jan19235921@decb.aber.ac.uk>
	<DAVIS.93Jan22105234@passy.ilog.fr>
Organization: University College of Wales, Aberystwyth
X-Old-Subject: Re: FAQ  Part 1 (of 2) [ objects, closures, continuations ]

>>> On 22 Jan 93 09:52:34 GMT, davis@passy.ilog.fr (Harley Davis) said:

Davis> In article <PCG.93Jan19235921@decb.aber.ac.uk> pcg@aber.ac.uk
Davis> (Piercarlo Grandi) writes:

pcg> (Bob Hathaway) said:

   pcg> More precisely objects are values of a procedure instance
   pcg> (closure/continuation) record type.

   objsys> Since the FAQ will typically be for newcomers, could you
   objsys> please put the last sentence in English and/or give
   objsys> references?

pcg> The references are easily produced: "Hierarchical Program
pcg> Structures", in "Structured Programming", Academic Press, and
pcg> "Structure and Interpretation of Computer Programs", MIT Press.

pcg> In particular they show that (in class based OO languages) classes
pcg> are procedures, and objects are procedure instances; closures if
pcg> the language is a traditional OO one, and continuations if the
pcg> language is an actor OO one.

Davis> Classes and objects are not procedures;

First, this is not what I wrote; I wrote:

pcg> (in class based OO languages) classes are procedures, and objects
pcg> are procedure instances

Both the qualification in parenthesis and the dictinction between
procedures and procedure instances are important (even if for the sake
of extreme brevity, and I regret that, I did not make the first explicit
in the very short frase: "More precisely objects are values of a
procedure instance (closure/continuation) record type.").

Second, classes and objects are procedures and procedure instances in
two very real senses; that this is how historically they were
'invented', both in capability systems (the PDP-1) and in OO languages
(Simula 67); and that this is how they actually behave, even if this is
disguised by syntax and foggy terminology (the very special status of a
C++ constructor can only be fully understood if it is considered the
body of its class seen as a procedure, and even its invocation syntax is
inspired to that).

Davis> rather, they can be implemented or, perhaps, thought of as
Davis> procedures in some languages for some OO models.

Indeed: implemented *and* thought of as procedures in most OO languages
for the dominant OO model, the one originating from Simula 67 (and
virtually all capability systems, I am sorry to report; I wish it were
different).

Davis>  Two reasons:

Davis> 1. In latently typed languages with first-class procedures, most
Davis>    objects (except for real procedures) will return false when asked
Davis>    if their type is procedure.

So what, except in Simula 67 even the syntax does not resemble much that
of a procedure definition or invocation, but this should not fool us.

Davis> 2. The simplistic SICP OO implementation in terms of closures does not
Davis>    account for multi-methods.

The simplistic SICP OO "implementation" is isomorphic with how classes
and objects are implemented *and* behave in 90% of current OO languages,
e.g. C++, Objective C, Eiffel, Smalltalk, and so on; so whetther
simplistic or not, it has some historical and practical importance.

On the other hand I completely agree that such a simplistic, Simula 67
derived notion of class and object does not account for multimethods,
and indeed that this is regrettable. I had written:

pcg> (in class based OO languages)

where maybe I should have written 'in Simula 67 derived OO languages'.
IMNHO with multimethods OO languages are not as class based as
hierarchically oriented ones.

I had indeed gone further than this in a subsequent article:

pcg> * Having objects be procedure instances and classes be procedures has
pcg>   the unfortunate effect of being constrained by the nested scope
pcg>   properties of procedures in conventional languages. This results in
pcg>   difficulties with non hierarchical program structures: not by chance
pcg>   the seminal paper on the OO decomposition paradigm by Dahl an Hoare
pcg>   has title "Hierarchical Program Structures". After CLOS I think it it
pcg>   is apparent (to me at least) that getting to OO via the more direct
pcg>   overloading route is more flexible, as overloading can be made to
pcg>   depend on multiple parameters, not just on that of the procedure
pcg>   instance.

Well, we now know all this is apprent to you as well as me. Wonderful. :-)

Davis> Also, what is the difference between a "procedure" and a
Davis> "procedure instance"?

I really meant "procedure instance". A procedure is one thing, an
instantiated procedure (a closure or a continuation) is quite another
thing.

Davis> Perhaps you meant to say that a class can be thought
Davis> of as a procedure which returns procedures.

No, I did not mean this. What returns procedure _instances_ (objects)
given a procedure (class) is the 'NEW' operator.

I believe, from your background, that you know the distinction, so maybe
I am expressing myself poorly. I will try to be more explicit:

A procedure is a tuple consisting of a context (the parameters and the
local variables) and a block.

Calling a procedure involves four  steps (as far as I know only the
obscure SL5 language is "reflective" enough to allow the programmer to
distinguish them):

	1 a new tuple is created with a copy of the context and
	  the same block ('copying')

	2 it is transformed into a closure by setting up the binding
	  between the names of the parameters in the context and the
	  values of the arguments ('filling')

	3 it is transformed into a continuation by associating with
	  it an inactive thread state. ('making')

	4 the inactive thread state is continued/resumed by the current
	  thread. ('continuining')

Usually only #2 and #3 are called procedure instances; and the term
procedure instance is most often used in the literature in the context
of recursive procedures, where the same procedure can have as many
instances as there are recursion levels (contour model and all that).

To make it clearer, I will give come examples:

* 'function'/'closure' in Lisp gives the programmer a handle on the result
  of step #2 (in shallow bound Lisps one can choose which bindings are
  put into the context, while in deep bound Lisps the entire environment
  is).

* 'call/cc' in Scheme gives the programmer a handle on the result of
  step #3.

* freezing arguments (aka partial application) in Pop-2 performs #1 and
  #2 _only_.

* 'NEW' in Simula 67 performs steps #1-4, and 'DETACH' and 'RESUME'
  operate at the step #4 level; so in Simula 67 objects can be either
  closures (the body of the class contains no 'DETACH' was empty) or
  continuations (after a 'DETACH'). Thus it can be said that Simula 67
  gave birth to both the closure (passive object ?) and actor (active
  object?) based OO language families (typically programs in Simula 67
  are written in closure based style for non simulation applications,
  and in actor based style for discrete simulation application -- this
  is very clear from the original Simula 67 reference manual).

* 'new' in C++ does steps #1-4, but there is no primitive to suspend and
  resume the instance/object (the constructor must run to completion),
  so in C++ objects are all closures (like in Eiffel, Objective C, and
  so on).

* Under Unix 'exec' performs steps #1-2, 'fork' is steps #3-4 (in a
  rather funny way, let me say), and 'pause' and 'kill' operate at the
  step #4 level.

* protected procedures/type managers in capability architectures are
  the result of performing steps #1-3.
Newsgroups: comp.object