From: rif
Subject: Basic defmethod question
Date: 
Message-ID: <wj0znfbdf7s.fsf@five-percent-nation.mit.edu>
I have a class (matrix), for which I've defined a print-object method.

(defmethod print-object ((m matrix) s)
    (stuff-to-print-a-matrix))

This does exactly what I want in the repl.

Now I want to save (and load) matrices in files, so I need to somehow
surpress my definition, which prints only abbreviated information.
How should I go about this?  

The underlying implementation of a matrix is just a struct, so I'm
hoping that if I can get rid of this print-object method, I can just
use read and write to save and load matrices.

Any help is appreciated.

Cheers,

rif

From: Barry Margolin
Subject: Re: Basic defmethod question
Date: 
Message-ID: <%AUpb.359$lK3.0@news.level3.com>
In article <···············@five-percent-nation.mit.edu>,
rif  <···@mit.edu> wrote:
>
>I have a class (matrix), for which I've defined a print-object method.
>
>(defmethod print-object ((m matrix) s)
>    (stuff-to-print-a-matrix))
>
>This does exactly what I want in the repl.
>
>Now I want to save (and load) matrices in files, so I need to somehow
>surpress my definition, which prints only abbreviated information.
>How should I go about this?  
>
>The underlying implementation of a matrix is just a struct, so I'm
>hoping that if I can get rid of this print-object method, I can just
>use read and write to save and load matrices.

(defparameter *abbreviate-print-matrix* nil)
(defun my-print (object stream)
  (let ((*abbreviate-print-matrix* t))
    (print object stream)))
(defmethod print-object ((m matrix) s)
  (if *abbreviate-print-matrix*
      (print-abbreviated-matrix m s)
      (print-full-matrix m s)))

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Brian Downing
Subject: Re: Basic defmethod question
Date: 
Message-ID: <LWUpb.107052$Tr4.286976@attbi_s03>
In article <···············@five-percent-nation.mit.edu>,
rif  <···@mit.edu> wrote:
> I have a class (matrix), for which I've defined a print-object method.
> 
> (defmethod print-object ((m matrix) s)
>     (stuff-to-print-a-matrix))
> 
> This does exactly what I want in the repl.
> 
> Now I want to save (and load) matrices in files, so I need to somehow
> surpress my definition, which prints only abbreviated information.
> How should I go about this?  
> 
> The underlying implementation of a matrix is just a struct, so I'm
> hoping that if I can get rid of this print-object method, I can just
> use read and write to save and load matrices.

Using *PRINT-READABLY* would seem to be a decent option, as with it
bound to T you should have a guarantee that you'll get an error if you
try and print anything else that doesn't have a built-in readable form.

* (defstruct foo bar)   
FOO
* (defmethod print-object ((obj foo) stream)
    (if (not *print-readably*)
        (format stream "#<It's a foo!  With a bar of ~S>" (foo-bar obj)) 
        (call-next-method)))
#<Standard-Method PRINT-OBJECT (FOO T) {48185335}>
* (make-foo)
#<It's a foo!  With a bar of NIL>
* (let ((*print-readably* t)) (print (make-foo)))
#S(FOO :BAR NIL) 
#<It's a foo!  With a bar of NIL>

But I admit I don't really understand the spec enough to know of any
negative consequences of the above.  I would be curious if anybody else
knows of reasons not to do this, or better ideas.

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: rif
Subject: Re: Basic defmethod question
Date: 
Message-ID: <wj01xsn548i.fsf@five-percent-nation.mit.edu>
I was incorrect when I stated that matrix was a structure.  It was a
class.  So now, when I print one out by (call-next-method), I just get
something like:

#<MATRIX:MATRIX {4888C46D}>

I can imagine writing a print method that prints out all the info, but
is there any direct way to print one so that I can use read to read a
matrix object back in, without having to parse it myself?
(call-next-method) complains that there's no way to print a MATRIX
readably.

rif
From: Barry Margolin
Subject: Re: Basic defmethod question
Date: 
Message-ID: <RS8qb.368$lK3.24@news.level3.com>
In article <···············@five-percent-nation.mit.edu>,
rif  <···@mit.edu> wrote:
>
>I was incorrect when I stated that matrix was a structure.  It was a
>class.  So now, when I print one out by (call-next-method), I just get
>something like:
>
>#<MATRIX:MATRIX {4888C46D}>
>
>I can imagine writing a print method that prints out all the info, but
>is there any direct way to print one so that I can use read to read a
>matrix object back in, without having to parse it myself?
>(call-next-method) complains that there's no way to print a MATRIX
>readably.

CLOS doesn't provide a default read syntax for its instances, because
there's no universally right way to do this.  If you want your objects to
print readably, you have to define a read syntax and then make your
PRINT-OBJECT method use this syntax.

This is similar to the reason for the MAKE-LOAD-FORM generic function: CLOS
doesn't presume to know enough about the internal structure of objects to
be able to recreate them itself.

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: rif
Subject: Re: Basic defmethod question
Date: 
Message-ID: <wj07k2e3h53.fsf@five-percent-nation.mit.edu>
> CLOS doesn't provide a default read syntax for its instances, because
> there's no universally right way to do this.  If you want your objects to
> print readably, you have to define a read syntax and then make your
> PRINT-OBJECT method use this syntax.

Ah.  What's the essential difference that makes a default read syntax
a good idea for structures, but not for CLOS classes?

rif
From: Kent M Pitman
Subject: Re: Basic defmethod question
Date: 
Message-ID: <wkvfpypv77.fsf@nhplace.com>
rif <···@mit.edu> writes:

> > CLOS doesn't provide a default read syntax for its instances, because
> > there's no universally right way to do this.  If you want your objects to
> > print readably, you have to define a read syntax and then make your
> > PRINT-OBJECT method use this syntax.
> 
> Ah.  What's the essential difference that makes a default read syntax
> a good idea for structures, but not for CLOS classes?

The fact that DEFSTRUCT was created in our early starry-eyed days
when we didn't think it was a bad idea and DEFCLASS was created
later on when we knew better.
From: Barry Margolin
Subject: Re: Basic defmethod question
Date: 
Message-ID: <VFbqb.377$lK3.136@news.level3.com>
In article <··············@nhplace.com>,
Kent M Pitman  <······@nhplace.com> wrote:
>rif <···@mit.edu> writes:
>
>> > CLOS doesn't provide a default read syntax for its instances, because
>> > there's no universally right way to do this.  If you want your objects to
>> > print readably, you have to define a read syntax and then make your
>> > PRINT-OBJECT method use this syntax.
>> 
>> Ah.  What's the essential difference that makes a default read syntax
>> a good idea for structures, but not for CLOS classes?
>
>The fact that DEFSTRUCT was created in our early starry-eyed days
>when we didn't think it was a bad idea and DEFCLASS was created
>later on when we knew better.

That might be a good explanation, except that Maclisp DEFSTRUCT didn't have
a default read syntax.  Wasn't #S a Common Lisp innovation?

I think the answer is simply that structures are considered simpler that
classes.  Structures are usually used similarly to lists, just to collect
some data together; lists are typically homogeneous and/or unordered
collections, while structures are heterogeneous (either in data type or
role).

Classes, on the other hand, are part of an object-oriented framework.
They're active objects, and provide mechanisms for fine-grained control of
behavior depending on the data type.

It's true that CLOS extends these capabilities to structures and also
standard object types.  But I view this as an after-thought, a
generalization "because we could" type of thing.  Classes are a separate
category of types, and they're expected to be used when you want full
control of behavior, whereas standard types and structures come with lots
of default behavior.  There's this noticeable dichotomy between the
built-in types and the user-defined types that you get from classes.

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kent M Pitman
Subject: Re: Basic defmethod question
Date: 
Message-ID: <wkad7afx2x.fsf@nhplace.com>
Barry Margolin <··············@level3.com> writes:

> In article <··············@nhplace.com>,
> Kent M Pitman  <······@nhplace.com> wrote:
> >rif <···@mit.edu> writes:
> >
> >> Ah.  What's the essential difference that makes a default read syntax
> >> a good idea for structures, but not for CLOS classes?
> >
> >The fact that DEFSTRUCT was created in our early starry-eyed days
> >when we didn't think it was a bad idea and DEFCLASS was created
> >later on when we knew better.
> 
> That might be a good explanation, except that Maclisp DEFSTRUCT didn't have
> a default read syntax.  Wasn't #S a Common Lisp innovation?

It wasn't in Maclisp, since SFA's printed as #SFA-|foo|-12345.

But I believe #S(...) was in CLTL1.  [I don't have one handy to check.
Hopefully someone else will correct me if I misremember...]

CLOS came 10 years later.

> I think the answer is simply that structures are considered simpler that
> classes.

If that was the reason, it's a poor reason.  It's easy to create DEFSTRUCT
objects where #S cannot hope to do the right thing.

Regardless of the red herring of programming style (you mentioned
"object oriented" in a way that seemed to imply the bogus but
widespread use of it to refer to a style of programming rather than a
pattern of resulting data at runtime), the issue of whether #S is a
good technique for printing is independent of how the objects are
programmed--it has to do with what is connected to what and whether
(a) there are redundant structures internally that ought not be
printed, (b) there are inter-object pointers for which identity is
important and for which printing only one object (without its friends)
may lose this identity.

> [...] Classes are a separate
> category of types, and they're expected to be used when you want full
> control of behavior,

This part is probably a correct rendition of the intent, but ironically since
CLOS by itself didn't allow easy control of the issues that make the 
structure-class metaclass different than the standard-class metaclass, 
CLOS does not offer "full control", just "different control".

> whereas standard types and structures come with lots
> of default behavior.

That's an interesting characterization.  I never heard it offered as
a rationale, though.  (It's a little odd that little of the heaps of
pre-defined behavior you're talking about here here can be defined
using CLOS itself.)

> There's this noticeable dichotomy between the
> built-in types and the user-defined types that you get from classes.

We agree here.
From: Harald Hanche-Olsen
Subject: Object oriented (Was: Basic defmethod question)
Date: 
Message-ID: <pcoptg6wi0t.fsf_-_@thoth.math.ntnu.no>
+ Kent M Pitman <······@nhplace.com>:

| Regardless of the red herring of programming style (you mentioned
| "object oriented" in a way that seemed to imply the bogus but
| widespread use of it to refer to a style of programming rather than
| a pattern of resulting data at runtime)

Once again I am more intrigued by a parenthetical remark than about
what seemed to be the main issue at hand.  Would you like to expand a
bit on this?  What is bogus about the widespread use of "object
oriented", and what patterns of resulting data are you referring to?

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Peter Seibel
Subject: Re: Object oriented (Was: Basic defmethod question)
Date: 
Message-ID: <m3znfa8jd9.fsf@javamonkey.com>
Harald Hanche-Olsen <······@math.ntnu.no> writes:

> + Kent M Pitman <······@nhplace.com>:
> 
> | Regardless of the red herring of programming style (you mentioned
> | "object oriented" in a way that seemed to imply the bogus but
> | widespread use of it to refer to a style of programming rather than
> | a pattern of resulting data at runtime)
> 
> Once again I am more intrigued by a parenthetical remark than about
> what seemed to be the main issue at hand.  Would you like to expand a
> bit on this?  What is bogus about the widespread use of "object
> oriented", and what patterns of resulting data are you referring to?

I suspect Kent might point you to this paper of his. It's a good read.

  <http://www.nhplace.com/kent/PS/Name.html>

-Peter

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

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kent M Pitman
Subject: Re: Object oriented (Was: Basic defmethod question)
Date: 
Message-ID: <wkhe1ie13p.fsf@nhplace.com>
Peter Seibel <·····@javamonkey.com> writes:

> Harald Hanche-Olsen <······@math.ntnu.no> writes:
> 
> > + Kent M Pitman <······@nhplace.com>:
> > 
> > | Regardless of the red herring of programming style (you mentioned
> > | "object oriented" in a way that seemed to imply the bogus but
> > | widespread use of it to refer to a style of programming rather than
> > | a pattern of resulting data at runtime)
> > 
> > Once again I am more intrigued by a parenthetical remark than about
> > what seemed to be the main issue at hand.  Would you like to expand a
> > bit on this?  What is bogus about the widespread use of "object
> > oriented", and what patterns of resulting data are you referring to?
> 
> I suspect Kent might point you to this paper of his. It's a good read.
> 
>   <http://www.nhplace.com/kent/PS/Name.html>

The paper addresses the politics of my remark but I suppose it won't hurt
for me to address the substance at least a little...

I often prefer these days to refer to identity-oriented programming for
what we once called object-oriented.  To me, and to the original meaning
of the term, the very essence of object oriented programming is about the
shape of connected structure once programs were written.

So, for example, Lisp's characteristic of redefinable or dynamically 
loadable functions is a natural result of the fact that definitions are
stored in objects (symbols) and that you can, in an object-oriented way,
change the object in a way that is possible to model/describe within
the language such that a new definition is in effect.

Another might be the characteristic of being inspectable independently of
a running program.  That is, data has the ability to answer questions about
itself because data is not just "procedurally embedded" but is subject to
an external use protocol.

Now, I claim, it's not necessary to say how this protocol was created.
In some cases, it might be wired in by the system implementors in C or
assembly.  In other cases, it might be user-programmed.  What matters is
the access protocol, not the definition protocol.

After all, when you compile the program, the definition protocol goes away
(to some extent--there is, of course, still EVAL in Lisp ... not in Java
though).

I think it's a data abstraction violation to say how a program is defined.
I think what matters is how it behaves.  And to me, THAT is object-oriented.

Java happens to be object-oriented in the sense that it has
introspection protocols built into the JVM.  But the quality of being
organized into a particular organizational theory of programming (that
I'd think is better called "object-centric" or even
"object-chauvinist") is just a red herring, IMO.  Certainly the fact
that most or all of your ability to change the 'environment' "compiles
out" when you compile Java cripples its object-oriented nature.  

And the sense in which there is any object-oriented stuff left after
you compile C++ is just a fantasy, so I don't see that as object-oriented
at all, no matter how object-centric the programming paradigm tries to
make it look.
From: Michael Hudson
Subject: Re: Object oriented (Was: Basic defmethod question)
Date: 
Message-ID: <7h365hxhbg4.fsf@pc150.maths.bris.ac.uk>
Kent M Pitman <······@nhplace.com> writes:

> Java happens to be object-oriented in the sense that it has
> introspection protocols built into the JVM.  But the quality of being
> organized into a particular organizational theory of programming (that
> I'd think is better called "object-centric" or even
> "object-chauvinist") is just a red herring, IMO.  Certainly the fact
> that most or all of your ability to change the 'environment' "compiles
> out" when you compile Java cripples its object-oriented nature.  
> 
> And the sense in which there is any object-oriented stuff left after
> you compile C++ is just a fantasy, so I don't see that as object-oriented
> at all, no matter how object-centric the programming paradigm tries to
> make it look.

Bizarre.  As I was walking into work today I was thinking ... well,
pretty much exactly that[0].  Small world.

Cheers,
mwh

[0] in the context pondering how much better a place the world would
    be if Objective C had taken over and not C++.
-- 
  Ignoring the rules in the FAQ: 1" slice in spleen and prevention 
    of immediate medical care.
                                              -- Mark C. Langston, asr
From: Michael Livshin
Subject: Re: Object oriented
Date: 
Message-ID: <s3y8ut4mh2.fsf@laredo.verisity.com.cmm>
Kent M Pitman <······@nhplace.com> writes:

> I think it's a data abstraction violation to say how a program is
> defined.  I think what matters is how it behaves.  And to me, THAT
> is object-oriented.

this is very nicely formulated.

unfortunately, while I, for example, can relate to this point and
agree with it, it has to be admitted that a certain vicious cycle
exists here: namely, an outsider (i.e. a person not well-versed in the
realm of nice interactive language runtimes) may not be able to
appreciate the relative importance of program structure at runtime
vs. program structure at definition time, precisely *because* in his
world there's no way to meaningfully manipulate program state at
runtime (and, as a consequence, no desire to do so)!

-- 
I knew you weren't really interested.
From: Kent M Pitman
Subject: Re: Object oriented
Date: 
Message-ID: <wkwuadqrps.fsf@nhplace.com>
Michael Livshin <······@cmm.kakpryg.net> writes:

> Kent M Pitman <······@nhplace.com> writes:
> 
> > I think it's a data abstraction violation to say how a program is
> > defined.  I think what matters is how it behaves.  And to me, THAT
> > is object-oriented.
> 
> this is very nicely formulated.
> 
> unfortunately, while I, for example, can relate to this point and
> agree with it, it has to be admitted that a certain vicious cycle
> exists here: namely, an outsider (i.e. a person not well-versed in the
> realm of nice interactive language runtimes) may not be able to
> appreciate the relative importance of program structure at runtime
> vs. program structure at definition time, precisely *because* in his
> world there's no way to meaningfully manipulate program state at
> runtime (and, as a consequence, no desire to do so)!

No doubt.
From: Harald Hanche-Olsen
Subject: Re: Object oriented
Date: 
Message-ID: <pcor80lupfn.fsf@thoth.math.ntnu.no>
+ Michael Livshin <······@cmm.kakpryg.net>:

| -- 
| I knew you weren't really interested.

But I was!  And am!  (Hmm, had managed to miss Kent's Name article
although I've been to his web site several times.)

Some people say that Simula was the first object oriented language.
But (as far as I remember) the inventors of Simula did not use that
term.  However, it certainly encouraged object oriented thinking, at
least when you were using the language for the purpose it was designed
for.  Back then, I was much too hung up on syntax, so I thought it was
neat how an object's methods were syntactically embedded within the
object definition itself, often letting you determine the behaviour of
the object at a glance.  Now I realize that it was much more important
that there was a well defined protocol for activating and deactivating
objects.  Whereas the syntactic requirement of putting the method
definition inside the class definition really is a straitjacket which
stops you from even imagining such a thing as multi-methods.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Gareth McCaughan
Subject: Re: Object oriented
Date: 
Message-ID: <87fzh15bvq.fsf@g.mccaughan.ntlworld.com>
Harald Hanche-Olsen <······@math.ntnu.no> writes:

> + Michael Livshin <······@cmm.kakpryg.net>:
> 
> | -- 
> | I knew you weren't really interested.
> 
> But I was!  And am!  (Hmm, had managed to miss Kent's Name article
> although I've been to his web site several times.)

I think he was just quoting Marvin the Paranoid Android,
not making any comment on any of his readers' reactions
to the discussion...

-- 
Gareth McCaughan
.sig under construc
From: Michael Livshin
Subject: Re: Object oriented
Date: 
Message-ID: <s3u15h3twa.fsf@laredo.verisity.com.cmm>
Gareth McCaughan <·····@g.local> writes:

> Harald Hanche-Olsen <······@math.ntnu.no> writes:
>
>> + Michael Livshin <······@cmm.kakpryg.net>:
>> 
>> | -- 
>> | I knew you weren't really interested.
>> 
>> But I was!  And am!  (Hmm, had managed to miss Kent's Name article
>> although I've been to his web site several times.)
>
> I think he was just quoting Marvin the Paranoid Android,
> not making any comment on any of his readers' reactions
> to the discussion...

[ I'm far from thinking that a c.l.l. regular could miss the sig
  delimiter. :) ]

anyway, I can really relate to Harald's point, and perhaps even to
generalize it a little.  the thing about putting methods inside
classes is that it is an obvious optimization (both conceptual, since
it lets you put related things in one place, and syntactic, since it
lets you refer to instance slots as if they were local variables), and
all optimizations, as everyone knows (or should know), come at the
cost of some generality (in this case, the ability to define
multimethods naturally).  in this particular case the good side is
obvious to most people and the bad side is not, making the
optimization extremely seductive to them.

also, it's not a coincidence that method invocation in "traditional
OO" languages is sometimes called "message passing".  the name
"message passing" brings to mind networking.  indeed, single-dispatch
method invocation nicely generalizes to RPC (at least syntactically),
while multiple dispatch doesn't map to networking in any obvious way.
so people tend to see another (possible) conceptual optimization here.

wondering what's posessed the sigmonster today,
--m

-- 
I think we might have been better off with a slide rule.
                -- Zaphod Beeblebrox
From: james anderson
Subject: Re: Object oriented
Date: 
Message-ID: <3FAB6944.89D2EF60@setf.de>
Michael Livshin wrote:
> 
> ...
> 
> anyway, I can really relate to Harald's point, and perhaps even to
> generalize it a little.  the thing about putting methods inside
> classes is that it is an obvious optimization (both conceptual, since
> it lets you put related things in one place, and syntactic, since it
> lets you refer to instance slots as if they were local variables),

thre is nothing in clos which precludes that form of expression.
mcl, in its ccl days, implemented object-lisp, which reinforced that concept.

to implement object-lisp in clos took one macro. to implement a
multidimensional form of object-lisp would take one macro plus introspection,
but it would interfere with single-expression "class" definitions.

>   and
> all optimizations, as everyone knows (or should know), come at the
> cost of some generality (in this case, the ability to define
> multimethods naturally).  in this particular case the good side is
> obvious to most people and the bad side is not, making the
> optimization extremely seductive to them.
> 
> also, it's not a coincidence that method invocation in "traditional
> OO" languages is sometimes called "message passing".  the name
> "message passing" brings to mind networking.  indeed, single-dispatch
> method invocation nicely generalizes to RPC (at least syntactically),
> while multiple dispatch doesn't map to networking in any obvious way.
> so people tend to see another (possible) conceptual optimization here.

i've read this elsewhere as well, but have not yet seen it substantiated.
one would think that the graph is just annotated differently:

Barry Margolin wrote:
> 
> ...  There's no concrete object in CL
> that represents this combination, but I think it's a reasonable way to
> conceptualize the design, and I suppose it could even be used in
> implementations.
> 

...
From: Joel Ray Holveck
Subject: Re: Object oriented
Date: 
Message-ID: <87u15gpesv.fsf@thor.piquan.org>
>> also, it's not a coincidence that method invocation in "traditional
>> OO" languages is sometimes called "message passing".  the name
>> "message passing" brings to mind networking.  indeed, single-dispatch
>> method invocation nicely generalizes to RPC (at least syntactically),
>> while multiple dispatch doesn't map to networking in any obvious way.
>> so people tend to see another (possible) conceptual optimization here.
> i've read this elsewhere as well, but have not yet seen it substantiated.
> one would think that the graph is just annotated differently:

I agree!  My biggest project uses RPC (not Sun RPC) with multiple
dispatch.  I'm sending a function name and some type-tagged args down
the pipe.  My department has been using this for over two years, and
it seems to work fine, thank you very much.

It's not something I can think of as "message passing", but it
certainly is a quite straightforward RPC'd multiple-dispatch object
protocol.

Cheers,
joelh

-- 
Joel Ray Holveck - ·····@piquan.org
   Fourth law of programming:
   Anything that can go wrong wi
sendmail: segmentation violation - core dumped
From: Lennart Staflin
Subject: Re: Object oriented
Date: 
Message-ID: <m2fzh08hrq.fsf@Saturn.lan>
Joel Ray Holveck <·····@piquan.org> writes:

> I agree!  My biggest project uses RPC (not Sun RPC) with multiple
> dispatch.  I'm sending a function name and some type-tagged args down
> the pipe.  My department has been using this for over two years, and

Yeah, what pipe is that?

> it seems to work fine, thank you very much.
>
> It's not something I can think of as "message passing", but it
> certainly is a quite straightforward RPC'd multiple-dispatch object
> protocol.

The "Classic" object model, with objects containint state and methods
and message passing, fits reasonably well with distributed computing.
I don't think CLOS and multiple dispatch does. Nothing presented here
convince me otherwise.

//Lennart Staflin
From: Michael Livshin
Subject: Re: Object oriented
Date: 
Message-ID: <s3llqs42y3.fsf@laredo.verisity.com.cmm>
Lennart Staflin <·····@lysator.liu.se> writes:

> The "Classic" object model, with objects containint state and
> methods and message passing, fits reasonably well with distributed
> computing.

yes, but the fit is mostly syntactical.  I fear that one cannot just
take a program and CORBA'ize it without changing the design.  network
has latencies, and they cannot be ignored in the general case.

> I don't think CLOS and multiple dispatch does. Nothing presented
> here convince me otherwise.

going slightly offtopic: is there any existing network protocol that
involves more than two peers?  my knowledge in this area is rather
shallow, I'm afraid.

-- 
Portions of this broadcast have been prerecorded.
From: Daniel Barlow
Subject: Re: Object oriented
Date: 
Message-ID: <8765hw9ttt.fsf@noetbook.telent.net>
Michael Livshin <······@cmm.kakpryg.net> writes:

> anyway, I can really relate to Harald's point, and perhaps even to
> generalize it a little.  the thing about putting methods inside
> classes is that it is an obvious optimization (both conceptual, since
[...]
> multimethods naturally).  in this particular case the good side is
> obvious to most people and the bad side is not, making the
> optimization extremely seductive to them.

I'm not sure this is actually true except for people who've trained
themselves to think in "the OO way".

I remember when I first started to hear about OOP, the example given
was "in smalltalk you don't add 2 to 3, you send a message to the `2'
object asking it to add 3 to itself", and I really didn't see
what was so much more special about the 2 object than the 3 object
that it gets to control the show in this way.  

Of course, now I understand how do do it properly: there should be
an AdditionTerm class with methods to accept the arguments and
calculate the results

AdditionTerm at = new AdditionTerm();
at.setLeftArgument(new Integer(2));
at.setRightArgument(new Integer(3));
println(at.doCalculation());

This is obviously more intuitive and more maintainable than `2+3' as
procedural programmers would write it: if for example a need to use a
different definition of addition arose, we could accomodate it by
subclassing AdditionTerm

> I think we might have been better off with a slide rule.
>                 -- Zaphod Beeblebrox

No comment ;-)


-dan

-- 

   http://web.metacircles.com/cirCLe_CD - Free Software Lisp/Linux distro
From: Barry Margolin
Subject: Re: Object oriented
Date: 
Message-ID: <dzOqb.403$lK3.90@news.level3.com>
In article <··············@noetbook.telent.net>,
Daniel Barlow  <···@telent.net> wrote:
>I remember when I first started to hear about OOP, the example given
>was "in smalltalk you don't add 2 to 3, you send a message to the `2'
>object asking it to add 3 to itself", and I really didn't see
>what was so much more special about the 2 object than the 3 object
>that it gets to control the show in this way.  

I agree with you regarding the asymmetry, but I'm not sure your "solution"
is right, either.

>Of course, now I understand how do do it properly: there should be
>an AdditionTerm class with methods to accept the arguments and
>calculate the results

That implies some all-knowing AdditionTerm class that knows all the ways to
add different types of objects.

I think the proper way to conceptualize it is that there are (perhaps
anonymous) classes representing each of the computations integer+integer,
integer+float, complex+complex, complex+integer, etc.  When you "add 2 and
3", what you're actually doing is sending the "do-it" message to the
integer+integer instance whose slots are 2 and 3.

Since these parameters are typically so fleeting, a more likely way that
one might actually implement this is with those classes being singleton
classes containing no slots, just methods.  2 and 3 would be arguments to
the do-it method.  On the other hand, keeping individual "add X and Y"
objects around could be a way to implement common subexpression elimination
and memoizing -- the object could have a slot where it caches the result so
it doesn't have to recompute it each time (but you'd have to "intern" these
objects somewhere, which could just as easily be done by the singleton
class -- it just goes to show how flexible the object model is).

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Michael Livshin
Subject: Re: Object oriented
Date: 
Message-ID: <s3ptg44370.fsf@laredo.verisity.com.cmm>
Daniel Barlow <···@telent.net> writes:

> Michael Livshin <······@cmm.kakpryg.net> writes:
>
>> anyway, I can really relate to Harald's point, and perhaps even to
>> generalize it a little.  the thing about putting methods inside
>> classes is that it is an obvious optimization (both conceptual, since
> [...]
>> multimethods naturally).  in this particular case the good side is
>> obvious to most people and the bad side is not, making the
>> optimization extremely seductive to them.
>
> I'm not sure this is actually true except for people who've trained
> themselves to think in "the OO way".
>
> I remember when I first started to hear about OOP, the example given
> was "in smalltalk you don't add 2 to 3, you send a message to the `2'
> object asking it to add 3 to itself", and I really didn't see
> what was so much more special about the 2 object than the 3 object
> that it gets to control the show in this way.  

I'm always wary of programming style examples that involve
arithmetics.  if you think of programming not in the narrow sense of
slapping together wage calculators, but as an activity that involves
modeling parts of the world in order to decide stuff, you'll find that
arithmetics is a very singular thing.  numbers just are not things a
reasonable person^Wprogram should send messages to.  they pack no
state apart from their very values, so there's no good sense in
treating them as entities participating in any modeling.

> Of course, now I understand how do do it properly: there should be
> an AdditionTerm class with methods to accept the arguments and
> calculate the results
>
> AdditionTerm at = new AdditionTerm();
> at.setLeftArgument(new Integer(2));
> at.setRightArgument(new Integer(3));
> println(at.doCalculation());
>
> This is obviously more intuitive and more maintainable than `2+3' as
> procedural programmers would write it: if for example a need to use a
> different definition of addition arose, we could accomodate it by
> subclassing AdditionTerm

well, I guess it's always a good idea to read the post you are
replying to in its entirety before starting to write the reply.  I
should try doing that. :)

-- 
It's tough being a bug: You screech in a tree all night, trying to get
laid, and then freeze to death.  It's kind of how teenagers look at
life.
                  -- Fred Reed (<URL:http://www.fredoneverything.net>)
From: Harald Hanche-Olsen
Subject: Re: Object oriented
Date: 
Message-ID: <pcod6c323h5.fsf@thoth.math.ntnu.no>
+ Michael Livshin <······@cmm.kakpryg.net>:

| Gareth McCaughan <·····@g.local> writes:
| 
| > I think he was just quoting Marvin the Paranoid Android,
| > not making any comment on any of his readers' reactions
| > to the discussion...
| 
| [ I'm far from thinking that a c.l.l. regular could miss the sig
|   delimiter. :) ]

Heh.  No, I didn't miss it.  But who the heck is Marvin the Paranoid
Android?  Oh never mind, don't answer that, I'll google it.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Pascal Bourguignon
Subject: Re: Basic defmethod question
Date: 
Message-ID: <87ptg6nifg.fsf@thalassa.informatimago.com>
Kent M Pitman <······@nhplace.com> writes:

> rif <···@mit.edu> writes:
> 
> > > CLOS doesn't provide a default read syntax for its instances, because
> > > there's no universally right way to do this.  If you want your objects to
> > > print readably, you have to define a read syntax and then make your
> > > PRINT-OBJECT method use this syntax.
> > 
> > Ah.  What's the essential difference that makes a default read syntax
> > a good idea for structures, but not for CLOS classes?
> 
> The fact that DEFSTRUCT was created in our early starry-eyed days
> when we didn't think it was a bad idea and DEFCLASS was created
> later on when we knew better.

I think the "real" difference is  that a structure is pure data, while
an object is data and method encapsulated.

To really write out an object  you would have to dump the methods too,
(including the methods defined in the super-classes).

When you see:              "#S(MY-STRUCT :A 1 :B "bee" :C (A B C))"
you can pre-process it to: (defstruct my-struct (a) (b) (c))
to be able to read it as:  (MAKE-MY-STRUCT :A 1 :B "bee" :C (A B C))
and get the real stuff.

When you see:                     "#OBJECT(MY-CLASS :A 1 :B "bee" :C (A B C))"
you can't only pre-process it to: (defclass my-class (???) ((a) (b) (c)))
to be able to read:          (make-instance 'my-class :A 1 :B "bee" :C (A B C))
and get the real stuff;
in particular:
    (do-my-class-stuff (make-instance 'my-class :A 1 :B "bee" :C (A B C)))
does not work anymore.


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
From: Kent M Pitman
Subject: Re: Basic defmethod question
Date: 
Message-ID: <wksml1ye4e.fsf@nhplace.com>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Kent M Pitman <······@nhplace.com> writes:
> 
> > rif <···@mit.edu> writes:
> > > > CLOS doesn't provide a default read syntax for its instances,
> > > > because there's no universally right way to do this.  If you
> > > > want your objects to print readably, you have to define a read
> > > > syntax and then make your PRINT-OBJECT method use this syntax.
> > > 
> > > Ah.  What's the essential difference that makes a default read syntax
> > > a good idea for structures, but not for CLOS classes?
> > 
> > The fact that DEFSTRUCT was created in our early starry-eyed days
> > when we didn't think it was a bad idea and DEFCLASS was created
> > later on when we knew better.
> 
> I think the "real" difference is  that a structure is pure data, while
> an object is data and method encapsulated.

But it just isn't.

Methods in CLOS are not _in_ the object.  All objects are capable of
supporting methods.

You can write a PRINT-OBJECT method on a struct.

You can write user-defined methods on a struct or even on built-in classes.

> To really write out an object  you would have to dump the methods too,
> (including the methods defined in the super-classes).

Huh?  This doesn't make any sense.

> When you see:              "#S(MY-STRUCT :A 1 :B "bee" :C (A B C))"
> you can pre-process it to: (defstruct my-struct (a) (b) (c))
> to be able to read it as:  (MAKE-MY-STRUCT :A 1 :B "bee" :C (A B C))
> and get the real stuff.

Ignoring even DEFMETHOD, what if it was defined by 

 (defstruct (my-struct (:constructor struct (a b c))) a b c)

or

 (defstruct my-struct-1 a b c)
 (defstruct (my-struct (:include my-struct-1)))

Either of these will result in #S(MY-STRUCT :A 1 :B "bee" :C (A B C)) 
printout but has important setup structure you cannot merely "infer".

And nothing says there aren't also methods on this structure class.

> When you see:
>                    "#OBJECT(MY-CLASS :A 1 :B "bee" :C (A B C))"
> you can't only pre-process it to:
>                    (defclass my-class (???) ((a) (b) (c)))
> to be able to read:
>                    (make-instance 'my-class :A 1 :B "bee" :C (A B C))
> and get the real stuff;

You have the identical questions with structures, you're just not
realizing it and/or acknowledging it.

> in particular:
>     (do-my-class-stuff (make-instance 'my-class :A 1 :B "bee" :C (A B C)))
> does not work anymore.

I'm not sure what this is about.

It is certainly true that MAKE-INSTANCE only works reliably for 
STANDARD-CLASS and not necessarily for other metaclasses, but it's up
to the implementation to decide.  There is no obvious reason that
MAKE-INSTANCE couldn't have worked for structure classes, and I regard
it as regrettable that we didn't require it to work.  I think a conforming
implementation could add this as an extension.  

Nevertheless, this doesn't seem to be what you're saying.  What does
"does not work anymore" mean in this context?  What did work before
and what happened to break it?

What is all this pre-processing and where is it occurring?

There is a reason that standard-class and structure-class are called
that and not just class and structure.  Both are classes, they are just
different kinds of classes.  Their differences are pretty small, all
in all, in terms of capabilities.  They are made to appear larger by clumsy 
differences in programming interface for historical reasons, not by 
either practical fact of implementational difference nor even by 
the designers' intent in how you should use the two, and certainly not
in any philosophical or actual difference such as "this one 'contains'
methods" and "this one does not".
From: james anderson
Subject: Re: Basic defmethod question
Date: 
Message-ID: <3FAA29E0.86F80EB8@setf.de>
Kent M Pitman wrote:
> 
> ...
> 
> > in particular:
> >     (do-my-class-stuff (make-instance 'my-class :A 1 :B "bee" :C (A B C)))
> > does not work anymore.
> 
> I'm not sure what this is about.
> 
> It is certainly true that MAKE-INSTANCE only works reliably for
> STANDARD-CLASS and not necessarily for other metaclasses, but it's up
> to the implementation to decide.  There is no obvious reason that
> MAKE-INSTANCE couldn't have worked for structure classes, and I regard
> it as regrettable that we didn't require it to work.  I think a conforming
> implementation could add this as an extension.

it is nice that one at least has allocate-instance. it would be nice if one
were permitted to extend make-instance to include it.

...
From: Pascal Bourguignon
Subject: Re: Basic defmethod question
Date: 
Message-ID: <87oevpn1bd.fsf@thalassa.informatimago.com>
Kent M Pitman <······@nhplace.com> writes:
> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> > I think the "real" difference is  that a structure is pure data, while
> > an object is data and method encapsulated.
> 
> But it just isn't.
> 
> Methods in CLOS are not _in_ the object.  All objects are capable of
> supporting methods.

That's  a technicallity.   Of course,  we don't  duplicate  methods or
method  tables in  each objects.   But in  the principles  of  OO both
methods AND data  belong to the instances.  Some  OO systems allow for
the association of instance methods specific to each object.

 
> You can write a PRINT-OBJECT method on a struct.
> 
> You can write user-defined methods on a struct or even on built-in classes.

More  reasons to  have  defined a  readable  form for  objects as  for
structures in Lisp.  I just rationalized in principles.


> > To really write out an object  you would have to dump the methods too,
> > (including the methods defined in the super-classes).
> 
> Huh?  This doesn't make any sense.

An  object is  the encapsulation  of data  AND methods.   To  write an
objects you can't just write data,  you have to write the methods too.
Unfortunately,  it's rarely  done.  (Perhaps in  some  OODB where  the
objects can be  stored along with their .class or  with the methods in
sexp form?),

 
> > When you see:              "#S(MY-STRUCT :A 1 :B "bee" :C (A B C))"
> > you can pre-process it to: (defstruct my-struct (a) (b) (c))
> > to be able to read it as:  (MAKE-MY-STRUCT :A 1 :B "bee" :C (A B C))
> > and get the real stuff.
> 
> Ignoring even DEFMETHOD, what if it was defined by 
> 
>  (defstruct (my-struct (:constructor struct (a b c))) a b c)
> 
> or
> 
>  (defstruct my-struct-1 a b c)
>  (defstruct (my-struct (:include my-struct-1)))
> 
> Either of these will result in #S(MY-STRUCT :A 1 :B "bee" :C (A B C)) 
> printout but has important setup structure you cannot merely "infer".
> 
> And nothing says there aren't also methods on this structure class.
                                                               ^^^^^
 
> > When you see:
> >                    "#OBJECT(MY-CLASS :A 1 :B "bee" :C (A B C))"
> > you can't only pre-process it to:
> >                    (defclass my-class (???) ((a) (b) (c)))
> > to be able to read:
> >                    (make-instance 'my-class :A 1 :B "bee" :C (A B C))
> > and get the real stuff;
> 
> You have the identical questions with structures, you're just not
> realizing it and/or acknowledging it.

Indeed,   I'm   just  rationalizing.    The   unorthogonality  is   in
Common-Lisp, not in me or in Smalltalk.

 
> > in particular:
> >     (do-my-class-stuff (make-instance 'my-class :A 1 :B "bee" :C (A B C)))
> > does not work anymore.
> 
> I'm not sure what this is about.

An hypothetical method named do-my-class-stuff in the my-class class.

 
> Nevertheless, this doesn't seem to be what you're saying.  What does
> "does not work anymore" mean in this context?  What did work before
> and what happened to break it?

Since an object is  not pure data, to be able to  send a message to an
object this  object must have a  method to process  the message.  When
you  save only  the data  of  an object  you've not  saved the  object
because when you read back the  object, you don't have the methods any
more.   So you  can't do  anything  significant with  the object  data
you've read.

With a structure,  which is pure dead data, when  you've read back the
structure, you  can change its field  or read its fields  as you could
before.



> What is all this pre-processing and where is it occurring?

In the case of structure, it could be implemented trivially to have it
done automatically.  In  case of objects it could  be implemented only
at the  cost of saving  all the methods  of the object along  with its
data.


If I send you a file containing:

#S(person :first-name "Pascal" :family-name "Bourguignon" 
    :birthday (1900 1 1)
    :address ("P.O. Box 32131" "San Francisco, CA 94321")
    :salary (:yearly :eur 2000000/100))

you can easily rebuild the  structure definitions needed to read these
structures and you can easily process it (read or change the fields).



If I send you a file containing:

 #O(employee-of-informatimago
    :first-name "Pascal" :family-name "Bourguignon" 
    :birthday (1900 1 1)
    :address ("P.O. Box 32131" "San Francisco, CA 94321")
    :grade  4
    :salary (:yearly :eur 2000000/100))

you cannot build an object that will sensibly answer to the message:

    (increase-grade-and-salary employee)

because you don't know the rules  to increase the grade and the salary
used at the Informatimago Corporation.


I should send you a file containing:

#O(employee-of-informatimago
    (employee person)
    (:first-name "Pascal" :family-name "Bourguignon" 
     :birthday (1900 1 1)
     :address ("P.O. Box 32131" "San Francisco, CA 94321")
     :grade  4
     :salary (:yearly :eur 2000000/100))
    (employer ((self employee-of-informatimago))
        (find-corporation-named "Informatimago"))
    (increase-grade-and-salary ((self employee-of-informatimago))
        (if (< (grade self) 10)
            (progn
                (incf (grade self))
                (setf (salary self) (* (salary self)
                                       (+ 1.10 (/ (grade self) 100)))))
            (setf (salary self) (* 2 (salary self)))))
    (change-address ((self employee) new-address)
        (setf (address self) new-address)
        (employee-changed-address (employer self) new-address))
    ;; ...
    )

and much more to let you do anything sensible with an object.


Why do you think java hyped  its .class files for remote processing of
objects thru the web?

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
From: Thomas A. Russ
Subject: Re: Basic defmethod question
Date: 
Message-ID: <ymiptg5webk.fsf@sevak.isi.edu>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:


> Kent M Pitman <······@nhplace.com> writes:
> > Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> > > I think the "real" difference is  that a structure is pure data, while
> > > an object is data and method encapsulated.
> > 
> > But it just isn't.
> > 
> > Methods in CLOS are not _in_ the object.  All objects are capable of
> > supporting methods.
> 
> That's  a technicallity.   Of course,  we don't  duplicate  methods or
> method  tables in  each objects.   But in  the principles  of  OO both
> methods AND data  belong to the instances.  Some  OO systems allow for
> the association of instance methods specific to each object.

[snip]

> An  object is  the encapsulation  of data  AND methods. 

This is part of the philosophy that accompanies and motivates the design
of a certain class of OO systems, typified by Java and C++ (and CLU).
But for CLOS this just isn't true.  The CLOS model is really different
and it isn't just a technicality.  It is a clear philosophical and
design difference.

Ignoring metaclass issues and simplifying somewhat:
In CLOS classes encapsulate data.  Generic functions encapsulate
methods.

The separation of functional encapsulation and data encapsulation is
what makes multiple dispatch possible.  As such it is a fundamentally
different model of object-oriented programming than the dominant model.

Although not directly required by this separation, the practical need to
support the addition of new methods to existing generic functions as new
classes get defined also leads to one of the better ideas of CLOS with
regard to code reuse:  Namely the separation of of methods from objects.

Using the dominant model of OO, one cannot reuse a hammer to hold down
papers on a windy day, unless the original designer of the hammer class
had forseen this use.  Your only recourse if you want to use a hammer as
a paperweight is to design your own special subtype of hammer, and only
use it to hold down weights.  Fortunately the real world doesn't work
like this.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Tim Bradshaw
Subject: Re: Basic defmethod question
Date: 
Message-ID: <ey3sml1irc8.fsf@cley.com>
* Pascal Bourguignon wrote:
> [...] But in the principles of OO methods AND data belong to the
> instances. [...]  Indeed, I'm just rationalizing.  The
> unorthogonality is in Common-Lisp, not in me or in Smalltalk. [...]

I'm sorry, your brain has malfunctioned. We will have to melt you down
for glue.  Trained operatives will be arriving shortly to begin the
process.  Please do not resist.
From: lin8080
Subject: Re: Basic defmethod question
Date: 
Message-ID: <3FAE8148.7FFB8699@freenet.de>
Tim Bradshaw schrieb:

> I'm sorry, your brain has malfunctioned. We will have to melt you down
> for glue.  Trained operatives will be arriving shortly to begin the
> process.  Please do not resist.

OHh NOoo 

He writes cler and I like to read that....

stefan
From: Kent M Pitman
Subject: Re: Basic defmethod question
Date: 
Message-ID: <wkznf9qrwm.fsf@nhplace.com>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> An  object is  the encapsulation  of data  AND methods.

Not in Common Lisp.  You can think this, but it's your own fantasy.
It's not how CL works.

Whether you do 
 (defclass foo ...)
 (defclass bar ...)
or
 (defstruct foo ...)
 (defstruct bar ...)
you can't say that
 (defmethod frob ((x foo) (y bar)) ...)
is part of either FOO or BAR.

CL is gf-centric in terms of how it organizes definitional storage, 
not object-centric.
From: Barry Margolin
Subject: Re: Basic defmethod question
Date: 
Message-ID: <KOwqb.394$lK3.218@news.level3.com>
In article <··············@nhplace.com>,
Kent M Pitman  <······@nhplace.com> wrote:
>CL is gf-centric in terms of how it organizes definitional storage, 
>not object-centric.

Although this is all technically true, I still think there's some value in
the traditional OO mind-set.  CL has to be gf-centric because of
multi-methods.  But I think we can treat those methods as "belonging" to a
particular combination of specializers.  There's no concrete object in CL
that represents this combination, but I think it's a reasonable way to
conceptualize the design, and I suppose it could even be used in
implementations.

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kent M Pitman
Subject: Re: Basic defmethod question
Date: 
Message-ID: <wkhe1hpaww.fsf@nhplace.com>
Barry Margolin <··············@level3.com> writes:

> In article <··············@nhplace.com>,
> Kent M Pitman  <······@nhplace.com> wrote:
> >CL is gf-centric in terms of how it organizes definitional storage, 
> >not object-centric.
> 
> Although this is all technically true, I still think there's some value in
> the traditional OO mind-set.  CL has to be gf-centric because of
> multi-methods.  But I think we can treat those methods as "belonging" to a
> particular combination of specializers.  There's no concrete object in CL
> that represents this combination, but I think it's a reasonable way to
> conceptualize the design, and I suppose it could even be used in
> implementations.

I wasn't trying to alienate the point of view, which I agree is useful,
but to say that you can't derive philosophical truths by empirical
observation of the storage technique, which seemed to be what was 
going on.

I like the way Tom Russ's analysis separated functional and data 
abstraction, btw.  His summary was clean, pointing out that data 
abstraction is centralized in the object, and functional abstraction
in the generic function.  Yes, if you make gfs and objects one to one,
you can construct the illusion that everything is "in" the object, but
as a practical fact, it's not.

And certainly, going back to the original issue, either way you look at
it, there is no difference in how structs and classes "internalize"
methods, since neither of them does.  The methods are on the outside in
both cases.  There is no way to look at a method call and say
"this does or doesn't manipulate this or that slot in the object",
regardless of whether the object is implemented as a struct or a class.
From: Edi Weitz
Subject: Re: Basic defmethod question
Date: 
Message-ID: <87fzh1zmo3.fsf@bird.agharta.de>
On 06 Nov 2003 13:12:06 +0100, Pascal Bourguignon <····@thalassa.informatimago.com> wrote:

> If I send you a file containing:
>
> #S(person :first-name "Pascal" :family-name "Bourguignon" 
>     :birthday (1900 1 1)
>     :address ("P.O. Box 32131" "San Francisco, CA 94321")
>     :salary (:yearly :eur 2000000/100))
>
> you can easily rebuild the structure definitions needed to read
> these structures and you can easily process it (read or change the
> fields).
>
> If I send you a file containing:
>
>  #O(employee-of-informatimago
>     :first-name "Pascal" :family-name "Bourguignon" 
>     :birthday (1900 1 1)
>     :address ("P.O. Box 32131" "San Francisco, CA 94321")
>     :grade  4
>     :salary (:yearly :eur 2000000/100))
>
> you cannot build an object that will sensibly answer to the message:
>
>     (increase-grade-and-salary employee)
>
> because you don't know the rules to increase the grade and the
> salary used at the Informatimago Corporation.

  * (defstruct foo a b)
  FOO
  * (defstruct (bar (:include foo)) c)
  BAR
  * (defmethod baz ((foo foo)) (* (foo-a foo) (foo-b foo)))
  #<Standard-Method BAZ (FOO) {4853E335}>
  * (make-bar :a 2 :b 21 :c 3)
  #S(BAR :A 2 :B 21 :C 3)
  * (baz *)
  42

So, if I send you a file containing

  #S(BAR :A 2 :B 21 :C 3)

you can build an object that will "sensibly answer to the message"

  (BAZ <object>)?

I'm impressed...

Edi.
From: Pascal Bourguignon
Subject: Re: Basic defmethod question
Date: 
Message-ID: <8765hxmwrd.fsf@thalassa.informatimago.com>
Edi Weitz <···@agharta.de> writes:

> On 06 Nov 2003 13:12:06 +0100, Pascal Bourguignon <····@thalassa.informatimago.com> wrote:
> 
> > If I send you a file containing:
> >
> > #S(person :first-name "Pascal" :family-name "Bourguignon" 
> >     :birthday (1900 1 1)
> >     :address ("P.O. Box 32131" "San Francisco, CA 94321")
> >     :salary (:yearly :eur 2000000/100))
> >
> > you can easily rebuild the structure definitions needed to read
> > these structures and you can easily process it (read or change the
> > fields).
> >
> > If I send you a file containing:
> >
> >  #O(employee-of-informatimago
> >     :first-name "Pascal" :family-name "Bourguignon" 
> >     :birthday (1900 1 1)
> >     :address ("P.O. Box 32131" "San Francisco, CA 94321")
> >     :grade  4
> >     :salary (:yearly :eur 2000000/100))
> >
> > you cannot build an object that will sensibly answer to the message:
> >
> >     (increase-grade-and-salary employee)
> >
> > because you don't know the rules to increase the grade and the
> > salary used at the Informatimago Corporation.
> 
>   * (defstruct foo a b)
>   FOO
>   * (defstruct (bar (:include foo)) c)
>   BAR
>   * (defmethod baz ((foo foo)) (* (foo-a foo) (foo-b foo)))
>   #<Standard-Method BAZ (FOO) {4853E335}>
>   * (make-bar :a 2 :b 21 :c 3)
>   #S(BAR :A 2 :B 21 :C 3)
>   * (baz *)
>   42
> 
> So, if I send you a file containing
> 
>   #S(BAR :A 2 :B 21 :C 3)
> 
> you can build an object that will "sensibly answer to the message"
> 
>   (BAZ <object>)?
> 
> I'm impressed...

I would not dare to implement a method on a mere structure. 

But  otherwise,   this  only  shows   that  Common-Lisp  is   as  much
object-oriented as  Smalltalk and it  should not have shied  away from
specifying a  printed representation  for objects and  a corresponding
read-macro.


-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
From: Paul F. Dietz
Subject: Re: Basic defmethod question
Date: 
Message-ID: <F42dnWmxYY4BzjeiRVn-vg@dls.net>
Pascal Bourguignon wrote:

> I would not dare to implement a method on a mere structure. 

Why not?

	Paul
From: Espen Vestre
Subject: Re: Basic defmethod question
Date: 
Message-ID: <kwislxzj4f.fsf@merced.netfonds.no>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> I would not dare to implement a method on a mere structure. 

You can build methods on symbols, numbers or anything else you like.
To understand and appreciate CLOS, you need to forget traditional S&M
OO.
-- 
  (espen)
From: Pascal Bourguignon
Subject: Re: Basic defmethod question
Date: 
Message-ID: <87wuadkzok.fsf@thalassa.informatimago.com>
Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:

> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> 
> > I would not dare to implement a method on a mere structure. 
> 
> You can build methods on symbols, numbers or anything else you like.
> To understand and appreciate CLOS, you need to forget traditional S&M
> OO.

Ok, I'll remove my chains, but one at a time :-)

-- 
__Pascal_Bourguignon__
http://www.informatimago.com/
From: Pascal Costanza
Subject: Re: Basic defmethod question
Date: 
Message-ID: <boebe4$dn1$1@newsreader2.netcologne.de>
Pascal Bourguignon wrote:

> Kent M Pitman <······@nhplace.com> writes:
> 
>>Pascal Bourguignon <····@thalassa.informatimago.com> writes:
>>
>>>I think the "real" difference is  that a structure is pure data, while
>>>an object is data and method encapsulated.
>>
>>But it just isn't.
>>
>>Methods in CLOS are not _in_ the object.  All objects are capable of
>>supporting methods.
> 
> 
> That's  a technicallity.   Of course,  we don't  duplicate  methods or
> method  tables in  each objects.   But in  the principles  of  OO both
> methods AND data  belong to the instances.  Some  OO systems allow for
> the association of instance methods specific to each object.

I think that's irrelevant. OOP was supposed to model the real world 
(whatever that means), and it makes perfect sense to think of messages 
being sent to a bunch of objects, and not just a single one, and them 
producing a response in conert.

Classes, inheritance, method tables, and the like, don't correspond to 
"real world" entities. They are just means to build the objects that do.


Pascal
From: Barry Margolin
Subject: Re: Basic defmethod question
Date: 
Message-ID: <lRyqb.400$lK3.391@news.level3.com>
In article <············@newsreader2.netcologne.de>,
Pascal Costanza  <········@web.de> wrote:
>Classes, inheritance, method tables, and the like, don't correspond to 
>"real world" entities. They are just means to build the objects that do.

Although they don't correspond to tangible objects, they were intended to
correspond to the way the real world "works".  Objects in the real world
can be categorized based on common structures and/or behaviors, and these
categories can often be put into hierarchies to reflect levels of
similarity or to override general principles with more specific
exceptions.

Much of this was initially done by AI researchers, when they developed
systems like Frames to capture real-world concepts and relationships.  OO
programming can be viewed as an extreme simplification of this idea.

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Daniel Barlow
Subject: Re: Basic defmethod question
Date: 
Message-ID: <87znf9p50l.fsf@noetbook.telent.net>
Pascal Costanza <········@web.de> writes:

> I think that's irrelevant. OOP was supposed to model the real world
> (whatever that means), and it makes perfect sense to think of messages
> being sent to a bunch of objects, and not just a single one, and them
> producing a response in conert.

Right.  Any time you have a "Manager" class - unless you're designing 
corporate workflow applications  - or a "Factory" object - except when
modelling a manufacturing industry - it's _probably_ a fiction caused
by having no sensible place to hang a method that doesn't really
belong to any single object at all.

> Classes, inheritance, method tables, and the like, don't correspond to
> "real world" entities. They are just means to build the objects that
> do.

What's the real-world entity corresponding to a StorageManagerImpl?



-dan

-- 

   http://web.metacircles.com/cirCLe_CD - Free Software Lisp/Linux distro
From: Pascal Costanza
Subject: Re: Basic defmethod question
Date: 
Message-ID: <boeisl$otg$1@newsreader2.netcologne.de>
Daniel Barlow wrote:

> What's the real-world entity corresponding to a StorageManagerImpl?

A storage manager?


Pascal

P.S.: ;)
From: Steven E. Harris
Subject: Re: Basic defmethod question
Date: 
Message-ID: <q67znf8w0f9.fsf@raytheon.com>
Daniel Barlow <···@telent.net> writes:

> Right.  Any time you have a "Manager" class - unless you're designing 
> corporate workflow applications  - or a "Factory" object - except when
> modelling a manufacturing industry - it's _probably_ a fiction caused
> by having no sensible place to hang a method that doesn't really
> belong to any single object at all.

Well put. I expressed a similar observation here�, and since writing
that things have gotten even worse. I've been to several design
reviews where someone comments, "I don't see any managers in your
diagrams. Most [other designs] have a few managers, so you should
probably put a few in." For the record, we work in C++.


Footnotes: 
� http://groups.google.com/groups?selm=87smy3aftk.fsf%40harris.sdo.us.ray.com

-- 
Steven E. Harris        :: ········@raytheon.com
Raytheon                :: http://www.raytheon.com
From: Barry Margolin
Subject: Re: Basic defmethod question
Date: 
Message-ID: <OUQqb.411$lK3.168@news.level3.com>
In article <···············@raytheon.com>,
Steven E. Harris  <········@raytheon.com> wrote:
>Daniel Barlow <···@telent.net> writes:
>
>> Right.  Any time you have a "Manager" class - unless you're designing 
>> corporate workflow applications  - or a "Factory" object - except when
>> modelling a manufacturing industry - it's _probably_ a fiction caused
>> by having no sensible place to hang a method that doesn't really
>> belong to any single object at all.
>
>Well put. I expressed a similar observation here�, and since writing
>that things have gotten even worse. I've been to several design
>reviews where someone comments, "I don't see any managers in your
>diagrams. Most [other designs] have a few managers, so you should
>probably put a few in." For the record, we work in C++.

As I think has been noted in the past in this group, many of the patterns
in Design Patterns exist to work around limitations of popular OO
languages.  CLOS often has built-in features that serve the same purposes
as these patterns, so it's not necessary to have explicit classes for those
roles.  For instance, a number of patterns are obviated by multimethods.

It's important to realize that each pattern doesn't *always* have to
correspond directly to a class.  The translation from pattern to
implementation is language dependent, and if the language provides a better
way to realize a pattern than a class, it's appropriate to use it.

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Joe Marshall
Subject: Re: Basic defmethod question
Date: 
Message-ID: <brroylya.fsf@ccs.neu.edu>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> An  object is  the encapsulation  of data  AND methods.   

`Not necessarily!'
    -- Mr. Bennett of the Argument Clinic (John Cleese)

See  http://www.paulgraham.com/reesoo.html


> To write an objects you can't just write data, you have to write the
> methods too.

That's not sufficient.  If the object is to work *exactly* as it did
before, it needs its entire context.  Anything less is an
approximation, and once you've decided that you can live with an
approximation, you have to decide exactly what approximation.
Structures make a decision for you, CLOS classes leave the decision up
to you.
From: Paul Foley
Subject: Re: Basic defmethod question
Date: 
Message-ID: <m23cd0wzyu.fsf@mycroft.actrix.gen.nz>
On 06 Nov 2003 13:12:06 +0100, Pascal Bourguignon wrote:

> Kent M Pitman <······@nhplace.com> writes:
>> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
>> > I think the "real" difference is  that a structure is pure data, while
>> > an object is data and method encapsulated.
>> 
>> But it just isn't.
>> 
>> Methods in CLOS are not _in_ the object.  All objects are capable of
>> supporting methods.

> That's  a technicallity.   Of course,  we don't  duplicate  methods or
> method  tables in  each objects.   But in  the principles  of  OO both
> methods AND data  belong to the instances.  Some  OO systems allow for
> the association of instance methods specific to each object.

So does CLOS -- that's what EQL specializers are for.
 
>> You can write a PRINT-OBJECT method on a struct.
>> 
>> You can write user-defined methods on a struct or even on built-in classes.

> More  reasons to  have  defined a  readable  form for  objects as  for
> structures in Lisp.  I just rationalized in principles.

I don't know why you see it as a reason to do that, but surely the
same argument could be applied to say that it's a reason _not_ to
have defined a readable representation for structure-class instances?!

>> > To really write out an object  you would have to dump the methods too,
>> > (including the methods defined in the super-classes).
>> 
>> Huh?  This doesn't make any sense.

> An  object is  the encapsulation  of data  AND methods.   To  write an
> objects you can't just write data,  you have to write the methods too.

That's really not true.  Many inferior OO systems put methods inside
objects, but that's really only a namespacing hack (perhaps pointing
out other deficiencies in the language), not some deep ontological
principle.

In CLOS, methods belong to generic functions, not to (other) objects.

[Even in those other languages, methods are generally attached to the
class (or some superclass), not the instance.  If you just want to
externalize an instance, you can write out something to identify its
class along with the instance data -- not the methods!]

>> > When you see:              "#S(MY-STRUCT :A 1 :B "bee" :C (A B C))"
>> > you can pre-process it to: (defstruct my-struct (a) (b) (c))
>> > to be able to read it as:  (MAKE-MY-STRUCT :A 1 :B "bee" :C (A B C))
>> > and get the real stuff.

It doesn't work like that.  If Lisp hasn't already evaluated a
DEFSTRUCT form defining MY-STRUCT when it sees a #S(MY-STRUCT ...),
you just get an error -- it doesn't automatically define the struct.
[It doesn't have enough information to do that]

> Why do you think java hyped  its .class files for remote processing of
> objects thru the web?

Java .class files are equivalent to FASL files, not text files with
#S(...) constructs.  You really want to talk about MAKE-LOAD-FORM, not
PRINT-OBJECT.  There's a reason MAKE-LOAD-FORM produces _two_ values.

-- 
Cogito ergo I'm right and you're wrong.                 -- Blair Houghton

(setq reply-to
  (concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))