From: Chris Capel
Subject: Prototype based programming in Lisp
Date: 
Message-ID: <737b61f3.0410271221.5dd3742d@posting.google.com>
Hi, all.

I've been reading _Godel, Escher, Bach: An Eternal Golden Braid_, by
Douglas Hofstadter, and he mentions at one point that the distinction
between classes and and instances is rather arbitrary and limiting, as
the following list shows (his example):

1) publication
2) newspaper
3) Pleasantville Inquirer
4) May 18's issue of the Inquirer
5) My copy of May 18's issue

In a language with a normal object system (like java, or even, in this
case, Lisp) one would generally only be concerned with two or three
adjacent levels, as problems are rarely concerned with a much wider
domain, and so one would choose the lowest number in the above list as
one's superclass, and subclass that or instantiate it as necessary.
However, this isn't a general solution. If one were to have
"Publication" as a superclass, and "book", "newspaper", and "catalog"
as subclasses, would one have "Pleasantville Inquirer" as a subclass
of "newspaper"? No, it's likely one would choose to make it an
instance of "newspaper". But what if your program requiredments
expanded and you wanted to differentiate based on the date? You can't
instantiate an instance. So perhaps you would be better of going back
and changing "Pleasantville Inquirer" to a subclass of newspaper and
causing individual articles to be instances.

But what's this? We just changed, in our design, an instance into a
class! How odd! Perhaps this speaks of a deeper isomorphism.
Hofstadter, perhaps unintentionally, predicted prototype based object
systems.

So my question is, what does lisp offer in the way of collapsing the
distinction between class and instance? I understand that CLOS by
itself isn't quite sufficient; does the MOP make up for some of this
lack? Are there any other object systems in modern use that take
advantage of this principle?

From: ··············@hotmail.com
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <1098915667.538850.169060@c13g2000cwb.googlegroups.com>
Paul Graham, in his _ANSI Common Lisp_, I believe, demonstrates a
simple object-oriented extension to Lisp which conflates instances and
classes.

He then proceeds to optimize the making of instances over the making of
classes, but that goes away from the main thrust of his argument which
is that the concept of "Lisp" already encompasses object-orientation.

Lisp is an unparalleled medium for creating expressive programming
languages. Your question is really one about language design: is it
possible to design a language with the expressiveness you want? With
Lisp, almost certainly. Is it an efficient way to address real
programming problems? Perhaps not, but that is an issue of language
design, not of a particular existing language.

CLOS makes a particular choice of expressiveness, with particular
restrictions to make efficient implementations more possible. There is
no reason that you have to make the same design choices in your own
language.
From: Chris Capel
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <10o0ufjsivuf17a@corp.supernews.com>
··············@hotmail.com wrote:

> ... the concept of "Lisp" already encompasses object-orientation.
> 
> Lisp is an unparalleled medium for creating expressive programming
> languages. Your question is really one about language design: is it
> possible to design a language with the expressiveness you want? With
> Lisp, almost certainly.

Yes, yes. That's why I'm posting here, as opposed to a C# group.

Say, do you know any attempts in this direction for Common Lisp, or has
everyone pretty much been happy with CLOS, or not industrious (or
altruistic) enough to publish their custom object libraries separately from
their other code? I read that Garnet has a custom object system, but
written before CLOS was really available.

> Is it an efficient way to address real
> programming problems? Perhaps not, but that is an issue of language
> design, not of a particular existing language.

I know you weren't implying this, but do you know of any particular
shortcomings of a prototype-based object system being used in actual code?
I mean besides lending itself a bit more to spaghetti-like messes when used
injudiciously--that's a "shortcoming" of all advanced dynamic language
features.

Chris Capel
From: mikel
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <co1gd.12411$6q2.10592@newssvr14.news.prodigy.com>
Chris Capel wrote:
> ··············@hotmail.com wrote:
> 
> 
>>... the concept of "Lisp" already encompasses object-orientation.
>>
>>Lisp is an unparalleled medium for creating expressive programming
>>languages. Your question is really one about language design: is it
>>possible to design a language with the expressiveness you want? With
>>Lisp, almost certainly.
> 
> 
> Yes, yes. That's why I'm posting here, as opposed to a C# group.
> 
> Say, do you know any attempts in this direction for Common Lisp, or has
> everyone pretty much been happy with CLOS, or not industrious (or
> altruistic) enough to publish their custom object libraries separately from
> their other code? I read that Garnet has a custom object system, but
> written before CLOS was really available.
> 
> 
>>Is it an efficient way to address real
>>programming problems? Perhaps not, but that is an issue of language
>>design, not of a particular existing language.
> 
> 
> I know you weren't implying this, but do you know of any particular
> shortcomings of a prototype-based object system being used in actual code?
> I mean besides lending itself a bit more to spaghetti-like messes when used
> injudiciously--that's a "shortcoming" of all advanced dynamic language
> features.

Class-based systems can often resolve more stuff at compile time than 
can prototype-based systems, which means it's more challenging to make 
prototype-based systems fast.

When Jeff Piazza shifted from working on the Apple Dylan compiler to 
working on the NewtonScript implemmentation, he complained that 
NewtonScript had been designed to frustrate every known attempt at 
optimization known to language implementors.

There are no classes in a prototype-based sytem. Instead, you make new 
objects by cloning and mutating existing ones. You get the effect of 
inheritance by storing references to delegates -- objects to which 
messages are dispatched when the receiver doesn't know how to handle them.

Self has the concept of 'parents', which fill the role of delegates. 
There is a data parent (the parent from which the basic layout and 
content of the object's slots is taken) and the behavior parent (to 
which unknown messages are dispatched).

More general schemes are possible; for example, MacFrames and the 
Bauhaus frame system followed earlier frame systems (e.g. FRL and KRL) 
in providing a general mechanism by which you could create slots with 
custom delegation behavior.

All this is very dynamic stuff; you can change the number, name, and 
type of slots in any object at run time; you can change how values are 
stored in them (and how many values are stored in them). You can change 
how values are computed and returned when slots are referenced, and how 
they are changed by setters, and any of these things can involve 
arbitrarily complicated computations that are themselves looked up at 
runtime using user-defined algorithms.

The general idea is that objects are just collections of value-producing 
thingies that you can stick together any way you like, and change any 
time you want. To answer your question, all that dynamism makes it hard 
to optimize.

Both MacFrames and the Bauhaus frame system were fairly fast, especially 
MacFrames, but a lot of effort went into making them fast, and it was 
pretty easy for a user to make them slow again.

By the way, one of the tricks for making prototype-based systems faster 
is to secretly build classes under the covers so that things can be 
shared and statically computed. They have to have escape hatches built 
in, though, in case the user changes the structure of the objects. In 
effect, the classes behind the scenes work like caches for the results 
of dynamic lookups.
From: Christopher C. Stacy
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <usm7zlxgn.fsf@news.dtpq.com>
CLOS is not a knowledge representation system.
From: Chris Capel
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <10o0tt2lh8fda75@corp.supernews.com>
Christopher C. Stacy wrote:
> CLOS is not a knowledge representation system.

I'm not familiar with knowledge representation systems; I'm not sure I
understand. If a prototype-based object system is more general, and could
be used to implement, a more restrictive object system (even CLOS,
perhaps), why oughtn't it be used as a general-purpose object system, even
if macros are used to hide its full generality in normal usage? (I'm not
concerned with arguments about history here.) Why should prototype-based
object systems have anything in particular to do with knowledge
representation?

Chris Capel
From: Peter Seibel
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <m3acu7juyh.fsf@javamonkey.com>
Chris Capel <······@iba.nktech.net> writes:

> Christopher C. Stacy wrote:
>> CLOS is not a knowledge representation system.
>
> I'm not familiar with knowledge representation systems; I'm not sure
> I understand. If a prototype-based object system is more general,
> and could be used to implement, a more restrictive object system
> (even CLOS, perhaps), why oughtn't it be used as a general-purpose
> object system, even if macros are used to hide its full generality
> in normal usage?

Google "treaty of orlando".

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Pascal Costanza
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <clrnp1$o8a$1@newsreader2.netcologne.de>
Chris Capel wrote:
> Christopher C. Stacy wrote:
> 
>>CLOS is not a knowledge representation system.
> 
> I'm not familiar with knowledge representation systems; I'm not sure I
> understand. If a prototype-based object system is more general, and could
> be used to implement, a more restrictive object system (even CLOS,
> perhaps), why oughtn't it be used as a general-purpose object system, even
> if macros are used to hide its full generality in normal usage? (I'm not
> concerned with arguments about history here.) Why should prototype-based
> object systems have anything in particular to do with knowledge
> representation?

An important feature of class-based inheritance is that you can attach 
methods to classes and let the language semantics figure out which 
methods to call based on concrete arguments. In a prototype-based 
approach, there are no classes that can be used to automatically order 
methods, so you have to do this by hand, and the only way to do this is 
to explicitly wrap methods one by one. This is a severe limitation.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Peter Seibel
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <m34qke5x6s.fsf@javamonkey.com>
Pascal Costanza <········@web.de> writes:

> Chris Capel wrote:
>> Christopher C. Stacy wrote:
>> 
>>>CLOS is not a knowledge representation system.
>> I'm not familiar with knowledge representation systems; I'm not sure
>> I
>> understand. If a prototype-based object system is more general, and could
>> be used to implement, a more restrictive object system (even CLOS,
>> perhaps), why oughtn't it be used as a general-purpose object system, even
>> if macros are used to hide its full generality in normal usage? (I'm not
>> concerned with arguments about history here.) Why should prototype-based
>> object systems have anything in particular to do with knowledge
>> representation?
>
> An important feature of class-based inheritance is that you can attach
> methods to classes and let the language semantics figure out which
> methods to call based on concrete arguments. In a prototype-based
> approach, there are no classes that can be used to automatically order
> methods, so you have to do this by hand, and the only way to do this
> is to explicitly wrap methods one by one. This is a severe limitation.

You're talking about multiple-dispatch, right? Since most class-based
don't provide multiple dispatch either, this may be confusing to
someone who's not already familiar with Common Lisp. Or it's confusing
to me if you mean this statement to apply to singly-dispatched methods
as well. That is, don't most prototype-based languages dispatch based
on following a chain of "parent" prototypes. If I add a method to one
of the ancestral prototypes of an object, can't I then invoke invoke
that method on that object?

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Pascal Costanza
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <clrqpb$1u$1@newsreader2.netcologne.de>
Peter Seibel wrote:

>>An important feature of class-based inheritance is that you can attach
>>methods to classes and let the language semantics figure out which
>>methods to call based on concrete arguments. In a prototype-based
>>approach, there are no classes that can be used to automatically order
>>methods, so you have to do this by hand, and the only way to do this
>>is to explicitly wrap methods one by one. This is a severe limitation.
> 
> You're talking about multiple-dispatch, right?

No, this already applies to single dispatch.

> Since most class-based
> don't provide multiple dispatch either, this may be confusing to
> someone who's not already familiar with Common Lisp. Or it's confusing
> to me if you mean this statement to apply to singly-dispatched methods
> as well. That is, don't most prototype-based languages dispatch based
> on following a chain of "parent" prototypes. If I add a method to one
> of the ancestral prototypes of an object, can't I then invoke invoke
> that method on that object?

Yes, but assume you have a chain of objects and you want to insert a 
method in between (not just in front). What criterion do you use to 
select the object to add the method to?

Here is an illustration: In a class-based language you can have a hierarchy:

C <- D <- E

This:

(defmethod m ((receiver D) ...)
   ...)

...places the method in the middle of that hierarchy.

Now, in a prototype-based language, objects don't have names, just 
identity. So your chain looks like this:

o <- o <- o

How do you define a method on the second of three objects? You can't 
even be sure that you only get three objects and what the structure of 
the chain is, i.e., how it is composed in a concrete case.

You need a way to ask an object what kind of object it is. There you go. ;)


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Peter Seibel
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <m3wtxa4f22.fsf@javamonkey.com>
Pascal Costanza <········@web.de> writes:

> Peter Seibel wrote:
>
>>>An important feature of class-based inheritance is that you can attach
>>>methods to classes and let the language semantics figure out which
>>>methods to call based on concrete arguments. In a prototype-based
>>>approach, there are no classes that can be used to automatically order
>>>methods, so you have to do this by hand, and the only way to do this
>>>is to explicitly wrap methods one by one. This is a severe limitation.
>> You're talking about multiple-dispatch, right?
>
> No, this already applies to single dispatch.
>
>> Since most class-based
>> don't provide multiple dispatch either, this may be confusing to
>> someone who's not already familiar with Common Lisp. Or it's confusing
>> to me if you mean this statement to apply to singly-dispatched methods
>> as well. That is, don't most prototype-based languages dispatch based
>> on following a chain of "parent" prototypes. If I add a method to one
>> of the ancestral prototypes of an object, can't I then invoke invoke
>> that method on that object?
>
> Yes, but assume you have a chain of objects and you want to insert a
> method in between (not just in front). What criterion do you use to
> select the object to add the method to?
>
> Here is an illustration: In a class-based language you can have a hierarchy:
>
> C <- D <- E
>
> This:
>
> (defmethod m ((receiver D) ...)
>    ...)
>
> ...places the method in the middle of that hierarchy.
>
> Now, in a prototype-based language, objects don't have names, just
> identity. So your chain looks like this:
>
> o <- o <- o
>
> How do you define a method on the second of three objects? 

Well, you didn't define a method on "the second of three [classes]" in
your example. You defined it on a particular, named class that
happened to be in "the middle" of your hierarchy. If you want to do
that kind of thing in a prototype based language it seems like all you
have to do is assign names to certain important prototypes.

  (defun name-object (obj name)
     (setf (gethash name *named-objects*) obj))

  (defun named-object (name) (gethash name *named-objects*))

Now:

  (name-object (make-primordial-object) 'c)
  (name-object (clone (named-object 'c)) 'd)
  (name-object (clone (name-object 'd) 'e))

and:

  (setf (slot 'm (named-object 'd)) #'(lambda () ...))

is, it seems, the moral equivalent to  your:

  (defmethod m ((receiver D) ...) ...)

> You can't even be sure that you only get three objects and what the
> structure of the chain is, i.e., how it is composed in a concrete
> case.
>
> You need a way to ask an object what kind of object it is. There you go. ;)

Well, you need a way to refer to the objects you want to refer to. But
that doesn't seem to be that hard to arrange.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Pascal Costanza
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <clrur7$663$1@newsreader2.netcologne.de>
Peter Seibel wrote:

> Well, you need a way to refer to the objects you want to refer to. But
> that doesn't seem to be that hard to arrange.

Yes, but I think that's just reinventing classes, in the sense of that 
you will probably only name those objects that serve as templates for 
other objects.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Chris Capel
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <10o30u3afig6087@corp.supernews.com>
Pascal Costanza wrote:

> 
> Peter Seibel wrote:
> 
>> Well, you need a way to refer to the objects you want to refer to. But
>> that doesn't seem to be that hard to arrange.
> 
> Yes, but I think that's just reinventing classes, in the sense of that
> you will probably only name those objects that serve as templates for
> other objects.

But that isn't necessarily bad. Even if you do sometimes take advantage of
the full generality of prototype-based objects, there's no reason not to
use a subsystem isomorphic to traditional class systems in the usual cases,
or even to define macros such that most of your code looks like normal
class/instance code. Then when you do want to do something more advanced,
you can, and you get seamless integration of your "weird" objects and your
normal proto-classes/instances. And, as mikel has pointed out, the huge hit
in performance throughout, except in a mature implementation of a prototype
object system.

Chris Capel
From: Pascal Costanza
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <cls0s4$8pl$1@newsreader2.netcologne.de>
Chris Capel wrote:
> Pascal Costanza wrote:
> 
>>Peter Seibel wrote:
>>
>>>Well, you need a way to refer to the objects you want to refer to. But
>>>that doesn't seem to be that hard to arrange.
>>
>>Yes, but I think that's just reinventing classes, in the sense of that
>>you will probably only name those objects that serve as templates for
>>other objects.
> 
> But that isn't necessarily bad. Even if you do sometimes take advantage of
> the full generality of prototype-based objects, there's no reason not to
> use a subsystem isomorphic to traditional class systems in the usual cases,
> or even to define macros such that most of your code looks like normal
> class/instance code. Then when you do want to do something more advanced,
> you can, and you get seamless integration of your "weird" objects and your
> normal proto-classes/instances. And, as mikel has pointed out, the huge hit
> in performance throughout, except in a mature implementation of a prototype
> object system.

I don't think you gain a lot by doing this. But go ahead, do what you 
like, man! ;)


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Julian Stecklina
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <86fz3xvcyd.fsf@goldenaxe.localnet>
Pascal Costanza <········@web.de> writes:

> An important feature of class-based inheritance is that you can attach
> methods to classes and let the language semantics figure out which
> methods to call based on concrete arguments. In a prototype-based
> approach, there are no classes that can be used to automatically order
> methods, so you have to do this by hand, and the only way to do this
> is to explicitly wrap methods one by one. This is a severe limitation.

Let's create two prototypes and define methods on them:

(create-instance 'foo nil
		 (:bar 3))

(create-instance 'foo-2 foo)

(define-method :foo-method foo (obj)
   (gv obj :bar))  ; Return the value of :bar

(define-method :foo-method foo-2 (obj)
   (format t "FOO-2~%")
   (call-prototype-method obj))

In the listener:

CL-USER> (create-instance nil foo-2)
#k<KR-DEBUG:FOO-2-4>
CL-USER> (kr-send * :foo-method *)
FOO-2
3
CL-USER> 

What do you mean with that it does not order methods?

Regards,
-- 
                    ____________________________
 Julian Stecklina  /  _________________________/
  ________________/  /
  \_________________/  LISP - truly beautiful
From: Pascal Costanza
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <cltn4d$l4o$1@f1node01.rhrz.uni-bonn.de>
Julian Stecklina wrote:

> What do you mean with that it does not order methods?

Obviously nothing very meaningful. ;) I have confused naming and 
classification.

Thanks for pointing this out.

I have meant something else, but I have to think about it more deeply 
before I can put it in words...

Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Pascal Costanza
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <clpdg9$qht$1@newsreader2.netcologne.de>
Christopher C. Stacy wrote:
> CLOS is not a knowledge representation system.

...but based on one, and intentionally designed in a way to easily add 
such capabilities. See the papers on LOOPS at 
http://www2.parc.com/istl/groups/hdi/hdipublications.shtml and a cool 
page about its history at 
http://www2.parc.com/istl/members/stefik/loops.html


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Kenneth Tilton
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <ktilton-376730.19014827102004@nyctyp02-ge0.rdc-nyc.rr.com>
In article <····························@posting.google.com>,
 ·······@gmail.com (Chris Capel) wrote:

> Hi, all.
> 
> I've been reading _Godel, Escher, Bach: An Eternal Golden Braid_, by
> Douglas Hofstadter, and he mentions at one point that the distinction
> between classes and and instances is rather arbitrary and limiting, as
> the following list shows (his example):
> 
> 1) publication
> 2) newspaper
> 3) Pleasantville Inquirer
> 4) May 18's issue of the Inquirer
> 5) My copy of May 18's issue
> 
> In a language with a normal object system (like java, or even, in this
> case, Lisp) one would generally only be concerned with two or three
> adjacent levels, as problems are rarely concerned with a much wider
> domain, and so one would choose the lowest number in the above list as
> one's superclass, and subclass that or instantiate it as necessary.
> However, this isn't a general solution. If one were to have
> "Publication" as a superclass, and "book", "newspaper", and "catalog"
> as subclasses, would one have "Pleasantville Inquirer" as a subclass
> of "newspaper"? No, it's likely one would choose to make it an
> instance of "newspaper". But what if your program requiredments
> expanded and you wanted to differentiate based on the date? You can't
> instantiate an instance. So perhaps you would be better of going back
> and changing "Pleasantville Inquirer" to a subclass of newspaper and
> causing individual articles to be instances.

No, the Inquirer is still an instance of newspaper, and each issue is 
its own instance of an Issue class. Issues can have a slot for the 
newspaper of which they are an issue, or the newspaper can have a slot 
for issue instances, or both.

You cannot make Issue a subclass of Newspaper. If you do, then a slot 
such as publisher (who might publish more than one newspaper) gets 
replicated over all instances of the Issue. ie, each Issue instance has 
to redundantly describe the one newspaper instance actually out there in 
the Real World.

my2.

kenny
From: Chris Capel
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <10o0t7vlne2pq06@corp.supernews.com>
Kenneth Tilton wrote:

>> If one were to have
>> "Publication" as a superclass, and "book", "newspaper", and "catalog"
>> as subclasses, would one have "Pleasantville Inquirer" as a subclass
>> of "newspaper"? No, it's likely one would choose to make it an
>> instance of "newspaper". But what if your program requirements
>> expanded and you wanted to differentiate based on the date? You can't
>> instantiate an instance. So perhaps you would be better of going back
>> and changing "Pleasantville Inquirer" to a subclass of newspaper and
>> causing individual articles to be instances.
> 
> No, the Inquirer is still an instance of newspaper, and each issue is
> its own instance of an Issue class. Issues can have a slot for the
> newspaper of which they are an issue, or the newspaper can have a slot
> for issue instances, or both.

That doesn't seem quite right to me. Why would you make Issue a separate
class? If you're going to tie it up so closely with the "newspaper" idea
that you give it a newspaper slot to tie it back to the actual newspaper,
it might as well be a subclass of the particular newspaper. If you were to
give it a slot for its publication, which could be any sort of periodical,
then the new abstraction lineage might be justified as reflecting the real
world.

However, even if this particular example does happen to divide neatly into
classes and instances, surely you understand my point, that the distinction
isn't universally useful, and often limiting? Of course, not many people
would feel limited by it, never having used it to its full advantage. 

Out of curiosity, if the requirements happened to expand even further, to
include individual copies of issues, how you would lay out the hierarchy?
Would you simply add a slot to the Issue class to identify the copy and
instantiate another instance for each copy (assuming this isn't too
expensive memory-wise)? Would you create another class for this that points
back to the associated Issue instance?

> You cannot make Issue a subclass of Newspaper. If you do, then a slot
> such as publisher (who might publish more than one newspaper) gets
> replicated over all instances of the Issue. ie, each Issue instance has
> to redundantly describe the one newspaper instance actually out there in
> the Real World.

I don't see how this is a necessary feature of a prototype-based system. I
think there are a lot of subtle things you could do to implement
polymorphism and memory-sharing between copies of objects such that
redundancy isn't a problem at all.

Chris Capel
From: Chris Capel
Subject: Cells and object systems
Date: 
Message-ID: <10o0um3ra1km8c3@corp.supernews.com>
On an oblique note, Kenny, do you consider Cells as offering an alternative
way to accomplish the abstraction that's generally accomplished with an
object system, or do you use it in a complementary way?

Chris Capel
From: Kenneth Tilton
Subject: Re: Cells and object systems
Date: 
Message-ID: <ktilton-A57BEA.16404828102004@nycmny-nntp-rdr-03-ge1.rdc-nyc.rr.com>
First of all, re the other stuff, I broke off a response when I realized 
my ignorance of prototype-based systems was getting in the way badly. 
The only impression I have was that one does not even subclass so much 
as make copies of other instances. If that is even close, it would be 
hard to settle a question like "is this a subclass or instance?".

In article <···············@corp.supernews.com>,
 Chris Capel <······@iba.nktech.net> wrote:

> On an oblique note, Kenny, do you consider Cells as offering an alternative
> way to accomplish the abstraction that's generally accomplished with an
> object system, or do you use it in a complementary way?

Cells complement an object system. They establish dataflow between 
slots. We could make a special variable work like a cell, though it 
would have to be accessed through, well, accessor functions. Hmm, I 
guess I am saying we could have anonymous cells:

   (let ((g (make-instance 'game :start (get-internal-real-time
                  :game-over (c? (< 60 (t-min (- (cell-read *time*)
                                                 (^start))))))))
     (loop until (game-over g)
        do (cell-write *time* (get-internal-real-time))
           (play-around g)))

Of course in this case the game class could as well have a slot for the 
current time, so this is a bad example-- well, game should not have a 
slot for current time. Anyway, I am sure there would be good uses.

In my apps I cheat and have a *system* special var to which I bind an 
instance of System, and that is where I keep stuff like the time. That 
is not completely daffy because in fact that is where the application's 
concept of time comes from... let's just say that if someone hates OO 
(Paul, you out there?) and loves scads of global variables, Cells could 
still automatically move information through an application model.

kenny
From: Rahul Jain
Subject: Re: Cells and object systems
Date: 
Message-ID: <874qkbbrpd.fsf@nyct.net>
Kenneth Tilton <·······@nyc.rr.com> writes:

> We could make a special variable work like a cell, though it 
> would have to be accessed through, well, accessor functions.

It would simply need to be a symbol-macro.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Brian Downing
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <jdGgd.333041$3l3.100662@attbi_s03>
Kenneth Tilton wrote:
> No, the Inquirer is still an instance of newspaper, and each issue is 
> its own instance of an Issue class. Issues can have a slot for the 
> newspaper of which they are an issue, or the newspaper can have a slot 
> for issue instances, or both.
> 
> You cannot make Issue a subclass of Newspaper. If you do, then a slot 
> such as publisher (who might publish more than one newspaper) gets 
> replicated over all instances of the Issue. ie, each Issue instance has 
> to redundantly describe the one newspaper instance actually out there in 
> the Real World.

This isn't neccessarily true, as I'll try to show an example of below.

Kenneth Tilton wrote:
> First of all, re the other stuff, I broke off a response when I realized
> my ignorance of prototype-based systems was getting in the way badly.
> The only impression I have was that one does not even subclass so much
> as make copies of other instances. 

You don't make copies of instances, you inherit instances.

>                                    If that is even close, it would be
> hard to settle a question like "is this a subclass or instance?".

"Is this a subclass or instance?"  "Yes."

Here's an attempt to implement the example heirarchy

1) publication
2) newspaper
3) Pleasantville Inquirer
4) May 18's issue of the Inquirer
5) My copy of May 18's issue

with a cheezy prototype-based OO system I just brewed up.  Hopefully the
functions will be obvious enough.

------------------------------------------------------------------------
(let ((publication (send *root* 'make-child)))
  (setf (prop publication 'name) "name")
  (setf (prop publication 'publisher) "publisher")
  (setf (send publication 'publish)
        (lambda (self) (format t "~&We're publishing ~A!~%" self)))
  (setf (send publication 'print-self)
        (lambda (self stream)
          (print-unreadable-object (self stream)
            (format stream "Publication ~A (~A)"
                    (prop self 'name)
                    (prop self 'publisher)))))
  (describe publication)
  (let ((newspaper (send publication 'make-child)))
    (setf (prop newspaper 'date) "date")
    (setf (send newspaper 'print-self)
        (lambda (self stream)
          (print-unreadable-object (self stream)
            (format stream "Newspaper ~A (~A) [~A]"
                    (prop self 'name)
                    (prop self 'publisher)
                    (prop self 'date)))))
    (terpri) (describe newspaper)
    (let ((inquirer (send newspaper 'make-child)))
      (setf (prop inquirer 'name) "Pleasantville Inquirer")
      (setf (prop inquirer 'publisher) "Inquirer Inc.")
      (terpri) (describe inquirer)
      (let ((may-18th (send inquirer 'make-child)))
        (setf (prop may-18th 'date) "May 18th, 1904")
        (terpri) (describe may-18th)
        (let ((my-copy (send may-18th 'make-child)))
          (setf (prop my-copy 'owner) "Brian Downing")
          (format t "~%Now I scribble on the title...~&")
          (setf (prop my-copy 'name) "Ple-------lle In------")
          (format t "~%It's the ~A~&  and the owner is ~A.~&"
                  my-copy (prop my-copy 'owner))
          (send my-copy 'publish)
          (terpri) (describe my-copy)
          (format t "~%The issue is still untouched:~%~A~&" may-18th))))))
------------------------------------------------------------------------

And the output is:

------------------------------------------------------------------------
#<Publication name (publisher)> is an instance of class #<STANDARD-CLASS OBJ>.
The following slots have :INSTANCE allocation:
 PARENT     #<OBJ 0 {409AE2E9}>
 PROPS      (PUBLISHER "publisher" NAME "name")
 METHODS    (PRINT-SELF #<FUNCTION # {40A8F0DD}>
             PUBLISH #<FUNCTION # {40A70255}>)
 ID         1

#<Newspaper name (publisher) [date]>
is an instance of class #<STANDARD-CLASS OBJ>.
The following slots have :INSTANCE allocation:
 PARENT     #<Publication name (publisher)>
 PROPS      (DATE "date")
 METHODS    (PRINT-SELF #<FUNCTION # {40AAFE7D}>)
 ID         2

#<Newspaper Pleasantville Inquirer (Inquirer Inc.) [date]>
is an instance of class #<STANDARD-CLASS OBJ>.
The following slots have :INSTANCE allocation:
 PARENT     #<Newspaper name (publisher) [date]>
 PROPS      (PUBLISHER "Inquirer Inc." NAME "Pleasantville Inquirer")
 METHODS    NIL
 ID         3

#<Newspaper Pleasantville Inquirer (Inquirer Inc.) [May 18th, 1904]>
is an instance of class #<STANDARD-CLASS OBJ>.
The following slots have :INSTANCE allocation:
 PARENT     #<Newspaper Pleasantville Inquirer (Inquirer Inc.) [date]>
 PROPS      (DATE "May 18th, 1904")
 METHODS    NIL
 ID         4

Now I scribble on the title...

It's the #<Newspaper Ple-------lle In------ (Inquirer Inc.) [May 18th, 1904]>
  and the owner is Brian Downing.
We're publishing #<Newspaper Ple-------lle In------ (Inquirer Inc.) [May 18th, 1904]>!

#<Newspaper Ple-------lle In------ (Inquirer Inc.) [May 18th, 1904]>
is an instance of class #<STANDARD-CLASS OBJ>.
The following slots have :INSTANCE allocation:
 PARENT     #<Newspaper Pleasantville Inquirer (Inquirer Inc.) [May 18th, 1904]>
 PROPS      (NAME "Ple-------lle In------" OWNER "Brian Downing")
 METHODS    NIL
 ID         5

The issue is still untouched:
#<Newspaper Pleasantville Inquirer (Inquirer Inc.) [May 18th, 1904]>
------------------------------------------------------------------------

Another example of a successful prototype-based system that I'm
surprised hasn't been mentioned is MOO (http://www.hayseed.net/MOO/).
The hacked-up system in use above was sort of modeled after it.

That being said, I think the more traditional class/instance split is
more managable for most tasks, as well as opening the door for lots of
the advanced CLOS features.

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: David Sletten
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <gwWfd.31312$Kl3.9095@twister.socal.rr.com>
Chris Capel wrote:


> Hofstadter, perhaps unintentionally, predicted prototype based object
> systems.

> Are there any other object systems in modern use that take
> advantage of this principle?

JavaScript uses prototype-based rather than class-based inheritance. 
According to O'Reilly's 'Rhino' book (2e pg. 1), the languages Self and 
NewtonScript served as inspiration in this regard.

David Sletten
From: mikel
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <W91gd.35880$QJ3.29787@newssvr21.news.prodigy.com>
David Sletten wrote:
> Chris Capel wrote:
> 
> 
>> Hofstadter, perhaps unintentionally, predicted prototype based object
>> systems.
> 
> 
>> Are there any other object systems in modern use that take
>> advantage of this principle?
> 
> 
> JavaScript uses prototype-based rather than class-based inheritance. 
> According to O'Reilly's 'Rhino' book (2e pg. 1), the languages Self and 
> NewtonScript served as inspiration in this regard.

And NewtonScript was designed in a context where folks were aware of 
Self, though it wasn't so much directly inspired by Self. NewtonScript 
was designed mainly by Walter Smith and Steve Capps, and was based on a 
simple quasi-frame system that Capps wrote after Walter and some other 
Lispers explained the basic ideas of frame systems to him.

Frame systems were in the culture at Apple then; a little while before, 
Ruben Kleiman had written MacFrames, and had proposed that Apple add a 
'knowledge manager' to the Mac Toolbox. That didn't happen, but 
MacFrames later evolved into a cool project called SK8.

For a while I worked on an automated testing system designed by Matthew 
Maclaurin, called GATE, and built on MacFrames; then Matthew and 
afterwards I, went to work on Newton, where Larry Tesler started and I 
finished yet another frame system. That frame system was written in 
Dylan when it was more obviously a dialect of Lisp (it had s-expression 
syntax). I wrote it by implementing a prototype-based object system on 
Dylan's CLOS-like object system.

All the above-mentioned object systems were prototype-based object systems.
From: Pascal Costanza
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <clpcmu$p5h$1@newsreader2.netcologne.de>
Chris Capel wrote:

> So my question is, what does lisp offer in the way of collapsing the
> distinction between class and instance? I understand that CLOS by
> itself isn't quite sufficient; does the MOP make up for some of this
> lack? Are there any other object systems in modern use that take
> advantage of this principle?

CLOS already collapses the notions of class and instance to a certain 
extent. Each class is an object at the meta-level, and they can be used 
like "normal" objects, i.e., they can have slots and you can define 
methods on them. If you really want to make use of this you probably 
need to use the CLOS MOP, though (although a few limited meta-level 
capabilities are already part of CLOS itself).

You should read Andreas Paepcke's "User-Level Language Crafting" - an 
excellent introduction to the CLOS MOP, freely available on his website 
- and then, if you decide to go to a more detailed level, buy and read 
the book "The Art of the Metaobject Protocol" by Kiczales, des Rivieres 
and Bobrow. You can get cheap used copies on the net via amazon, 
abebooks, or the likes. It's really worth it, even if you decide not to 
use MOP features. In my opinion, it's one of the most important books 
about OOP ever written.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Kenneth Tilton
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <ktilton-2689BD.00291829102004@nyctyp01-ge0.rdc-nyc.rr.com>
In article <············@newsreader2.netcologne.de>,
 Pascal Costanza <········@web.de> wrote:

> Chris Capel wrote:
> 
> > So my question is, what does lisp offer in the way of collapsing the
> > distinction between class and instance? I understand that CLOS by
> > itself isn't quite sufficient; does the MOP make up for some of this
> > lack? Are there any other object systems in modern use that take
> > advantage of this principle?
> 
> CLOS already collapses the notions of class and instance to a certain 
> extent. Each class is an object at the meta-level, and they can be used 
> like "normal" objects, i.e., they can have slots and you can define 
> methods on them. 

I think that is different from what Chris is talking about, though it is 
a good example for learning to think about OO carefully. 

Chris feels that it is not always clear whether, for example, Issue 
should be an instance or subclass of Newspaper. This in the context of 
an application whose domain includes Publishing.

Yes, Issue and Newspaper are both instances of Standard-class, which 
itself is an instance of Standard-class. But now we are talking about a 
wholly different functional domain, viz, "How to implement an OO 
capability for programmers". That need not involve a MOP. The compiler 
could do everything with runtime structures invisible to the programmer 
(and their application code). 

So the fact that Issue is an instance of Standard-class is nothing like 
the possibility of making Issue an instance of Newspaper. 

kenny
From: Alan Crowe
Subject: Re: Prototype based programming in Lisp
Date: 
Message-ID: <867jp9v3t0.fsf@cawtech.freeserve.co.uk>
Chris Capel wrote

     I've been reading _Godel, Escher, Bach: An Eternal
     Golden Braid_, by Douglas Hofstadter, and he mentions
     at one point that the distinction between classes and
     and instances is rather arbitrary and limiting, as the
     following list shows (his example):

     1) publication
     2) newspaper
     3) Pleasantville Inquirer
     4) May 18's issue of the Inquirer
     5) My copy of May 18's issue

I think CLOS-classes, CLOS-instances, and CLOS-subclassing,
are concepts that are tightly tided to issues of program
organisation and code re-use. You should expect more
general, philosophical, notions of class, instance, and
subclass to live in a higher layer, built on top of the
object systems notion of object.

For example, I would justify having a newspaper as a
subclass of publication on the grounds that my program deals
with newspapers, weekly magazines, and books. All three have
a publisher, so I want to re-use the code pertaining to
publishers. So

(defclass publication ()
  (publisher))

(defclass weekly-magazine (publication)
  (publication-day))

(defclass book (publication)
  (publication-date))

Now it may be that a newspaper is sold to a different
publisher and here the purpose of my program starts to
matter. Since liability for libel will fall on the owner at
the time of publication of the offending issue, I might need
to keep track of the various publishers and the issues they
were responsible for.

(defclass periodical()
  (ownership-history))

(defclass newspaper (periodical)
  (title))

Am I denying that newspapers are publications? Not at
all. My CLOS-class hierarchy reflects my need for different
code for dealing with publishers and ownership. I expect to
represent the real world concept that a newspaper is a
publication in a different and more explicit way, so that I
do not tangle organising my code with respresenting reality.

Consider the relationship of items 4 and 5.

4) May 18's issue of the Inquirer
5) My copy of May 18's issue

The core of the relationship is mechanical reproduction.  4
is an abstraction and belongs to a different realm of being
to 5. I don't expect the object system to contain such
concepts. I expect to implement the concepts with code,
perhaps rather a lot of code.

I expect the copy to inherit from infrastructure I have
built up for dealing with physical objects.

(defclass locatable ()
  (position))

(defclass substantial ()
  (weight material))

(defmethod flammable ((x substantial))
  (ecase (material x)
    (paper t)
    (water nil)))

(defclass actual-copy (locatable substantial)
  (issue)
  (:default-initarg :material 'paper))

(defclass issue ()
  (list-of-stories list-of-adverts))

(defun print-newspaper (issue)
  (loop repeat print-run
        collect (make-instance 'actual-copy :issue issue)))

How the CLOS-stuff goes depends on what the program is
for. Perhaps copies all start with the same text, and the
program is supposed to keep track of articles get read in
which households, or something like that.

This is all speculation on my part. I've not done anything
with CLOS yet. Reading Keene's Object-Oriented Programming
in Common Lisp left me with the firm impression that CLOS
belongs to the technical side of programming not the
philosophical side of modelling the real world. I've been
learning CLOS quite thoroughly, see work in progress at

http://alan.crowe.name/clos/define-method-combination.html

If CLOS embodies any theory, it seems to me to be a theory
of organising code, not of representing knowledge.

Alan Crowe
Edinburgh
Scotland