From: ·········@gmail.com
Subject: CLOS
Date: 
Message-ID: <1182559507.945162.278830@c77g2000hse.googlegroups.com>
Hello. I don't have much experience using Common Lisp, so pardon me if
this question seems obvious.

I understand that CLOS is generally considered more powerful because
it has multiple dispatch, correct? I'm curious: based on that it seems
unlikely that CLOS implements dispatch using the "standard" vtable
technique. However, I'm not exactly sure if this is the case.

Basically my question is, do objects contain references to their
"member functions"? Presumably you wouldn't have "member" functions
per se, but it should be clear what I mean. Mostly I'm just curious if
CLOS "objects" require you to pass around the member functions or not.
(Of course I'm only talking about cases when you can't just import the
correct module.)

Thanks in advance,
Curtis

From: D Herring
Subject: Re: CLOS
Date: 
Message-ID: <stidncXCDK3m6OHbnZ2dnUVZ_veinZ2d@comcast.com>
·········@gmail.com wrote:
> Hello. I don't have much experience using Common Lisp, so pardon me if
> this question seems obvious.
> 
> I understand that CLOS is generally considered more powerful because
> it has multiple dispatch, correct? I'm curious: based on that it seems
> unlikely that CLOS implements dispatch using the "standard" vtable
> technique. However, I'm not exactly sure if this is the case.

As you might already know, C++ only uses vtables for "virtual" functions 
-- class methods where the API requires subclass-specific 
implementations of basic functionality.  Most of the "single dispatch" 
methods in C++ are simply treated as standard C functions -- with name 
mangling to create unique functions based on the parameter list and a 
hidden pointer to pass "this".

The CLOS allows multiple dispatch based on (IIRC) almost anything: base 
class, subclass, object instance, object contents, and even the time of 
day.  This power isn't free; CLOS calls are generally slower than normal 
function calls.  C++ trades multiple dispatch (and a dynamic language) 
for compiler optimizations (such as vtables).

> Basically my question is, do objects contain references to their
> "member functions"? Presumably you wouldn't have "member" functions
> per se, but it should be clear what I mean. Mostly I'm just curious if
> CLOS "objects" require you to pass around the member functions or not.
> (Of course I'm only talking about cases when you can't just import the
> correct module.)

I don't know much about CLOS implementations, but I think the answer to 
this is a solid no.

- Daniel
From: ·········@gmail.com
Subject: Re: CLOS
Date: 
Message-ID: <1182562677.927184.282580@u2g2000hsc.googlegroups.com>
> > Basically my question is, do objects contain references to their
> > "member functions"? Presumably you wouldn't have "member" functions
> > per se, but it should be clear what I mean. Mostly I'm just curious if
> > CLOS "objects" require you to pass around the member functions or not.
> > (Of course I'm only talking about cases when you can't just import the
> > correct module.)
>
> I don't know much about CLOS implementations, but I think the answer to
> this is a solid no.
>
> - Daniel

Ok, thanks. That's what I figured.


Just out of curiosity, how are streams represented in Common Lisp? Do
you need to pass around the stream methods, or is the needed
flexibility embedded in a base set of methods which then dispatch
based on the type?
From: Alex Mizrahi
Subject: Re: CLOS
Date: 
Message-ID: <467cda28$0$90271$14726298@news.sunsite.dk>
(message (Hello ··········@gmail.com)
(you :wrote  :on '(Fri, 22 Jun 2007 18:37:57 -0700))
(

 c> Just out of curiosity, how are streams represented in Common Lisp? Do
 c> you need to pass around the stream methods, or is the needed
 c> flexibility embedded in a base set of methods which then dispatch
 c> based on the type?

i think you'd better start with particular problem description and example.

do you need a custom streams? unfortunately, afaik it's not possible (or 
just not easy?) to do it in standard CL.
but there are so-called Gray streams:

STREAM-DEFINITION-BY-USER ("Gray Streams")
http://www.nhplace.com/kent/CL/Issues/stream-definition-by-user.html

it was not included into standard, but nevertheless, many implementations 
implement it, so you can use it to create custom streams.

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"I am everything you want and I am everything you need") 
From: ·········@gmail.com
Subject: Re: CLOS
Date: 
Message-ID: <1182606321.546797.132750@n2g2000hse.googlegroups.com>
On Jun 23, 3:30 am, "Alex Mizrahi" <········@users.sourceforge.net>
wrote:
> (message (Hello ··········@gmail.com)
> (you :wrote  :on '(Fri, 22 Jun 2007 18:37:57 -0700))
> (
>
>  c> Just out of curiosity, how are streams represented in Common Lisp? Do
>  c> you need to pass around the stream methods, or is the needed
>  c> flexibility embedded in a base set of methods which then dispatch
>  c> based on the type?
>
> i think you'd better start with particular problem description and example.
>
> do you need a custom streams? unfortunately, afaik it's not possible (or
> just not easy?) to do it in standard CL.
> but there are so-called Gray streams:
Customs streams would be the purpose of this, yes. I guess CL chose
the 3rd option-ignore it.
From: Jeronimo Pellegrini
Subject: Re: CLOS
Date: 
Message-ID: <f5i1k7$v6i$1@aioe.org>
On 2007-06-23, D Herring <········@at.tentpost.dot.com> wrote:
> The CLOS allows multiple dispatch based on (IIRC) almost anything: base 
> class, subclass, object instance, object contents, and even the time of 
> day.  This power isn't free; CLOS calls are generally slower than normal 
> function calls.

This is interesting. Suppose I have a method that I call on an object
thousands of times inside a loop. I should probably try not to do that,
right? But what's an efficient alternative?

A structure instead of a class, and just ordinary functions accessing
the structure?
Or, maybe keep using CLOS, but write memoizing wrappers for the methods
that need to be efficient (but if I have huge matrices, memoizing would
duplicate the needed memory).

Thanks,
J.
From: Barry Margolin
Subject: Re: CLOS
Date: 
Message-ID: <barmar-12BFF4.00302723062007@comcast.dca.giganews.com>
In article <············@aioe.org>,
 Jeronimo Pellegrini <···@aleph0.info> wrote:

> On 2007-06-23, D Herring <········@at.tentpost.dot.com> wrote:
> > The CLOS allows multiple dispatch based on (IIRC) almost anything: base 
> > class, subclass, object instance, object contents, and even the time of 
> > day.  This power isn't free; CLOS calls are generally slower than normal 
> > function calls.
> 
> This is interesting. Suppose I have a method that I call on an object
> thousands of times inside a loop. I should probably try not to do that,
> right? But what's an efficient alternative?

Most implementations make use of caches to optimize this.  While it's 
unlikely that GF calls will be as fast as ordinary function calls, it 
shouldn't be so bad that you need to avoid them.

And it sounds like you're optimizing prematurely.  Wait until you 
actually find that the program is running too slowly before worrying 
about whether GF's are the problem.  And then use a profiler to find out 
if that's really what it is.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Pascal Bourguignon
Subject: Re: CLOS
Date: 
Message-ID: <87hcozib4x.fsf@thalassa.lan.informatimago.com>
Jeronimo Pellegrini <···@aleph0.info> writes:

> On 2007-06-23, D Herring <········@at.tentpost.dot.com> wrote:
>> The CLOS allows multiple dispatch based on (IIRC) almost anything: base 
>> class, subclass, object instance, object contents, and even the time of 
>> day.  This power isn't free; CLOS calls are generally slower than normal 
>> function calls.
>
> This is interesting. Suppose I have a method that I call on an object
> thousands of times inside a loop. I should probably try not to do that,
> right? But what's an efficient alternative?
>
> A structure instead of a class, and just ordinary functions accessing
> the structure?
> Or, maybe keep using CLOS, but write memoizing wrappers for the methods
> that need to be efficient (but if I have huge matrices, memoizing would
> duplicate the needed memory).

Objective-C has the same problem, when you do dynamic dispatching,
finding the method is bound to be slower than a single function call.

However, implementations can be smart, and for example implement a
cache for the methods.  Amortized dispatch is then about as fast as
one or two function calls.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: Pascal Costanza
Subject: Re: CLOS
Date: 
Message-ID: <5e43fpF361qb5U1@mid.individual.net>
D Herring wrote:

> The CLOS allows multiple dispatch based on (IIRC) almost anything: base 
> class, subclass, object instance, object contents, and even the time of 
> day.  This power isn't free; CLOS calls are generally slower than normal 
> function calls.  C++ trades multiple dispatch (and a dynamic language) 
> for compiler optimizations (such as vtables).

Claims about CLOS being slow are highly exaggerated. It's just that the 
optimization model for generic functions is more complex than vtables.

Most generic functions only hold a couple of methods. This observation 
allows CLOS to tweak method dispatch to get very efficient code.

Assume that a generic function holds just one method where none of the 
parameters is specialized on a specific class. This means that the 
method is always applicable and is always the one that is to be 
executed. In that case the generic function can simply be replaced by 
that method. No dispatch is necessary at all (which in theory is 
actually better than vtables).

If there is one method with one parameter specialized to a specific 
class, CLOS doesn't need to use a "search" for applicable methods, but 
it can just use an if-test that tests the one parameter. If it is an 
instance of the particular class, the method is run, otherwise an error 
is signaled that no method is applicable.

If you have two methods, one with a specialization and one without - 
well, then it's just the same if-test, where one branch calls the 
specialized method and the other calls the unspecialized one.

For three methods you get a nested if-test, etc. pp., the principle 
should be clear by now. In other words, for a low number of methods, a 
generic function can efficiently perform method dispatch by way of a 
couple of nested if statements. Only if the number of methods grows 
beyond a certain size, a more general approaching using tables and 
caches becomes more feasible. And even then, a number of optimizations 
can be performed: For example, if it is known that none of the methods 
for a generic function specialize a certain parameter position, then 
that parameter position doesn't need to be taken into account at all in 
the internal tables and caches. Another corner case is that if only one 
parameter is ever specialized, you effectively get a mechanism similar 
to vtables (and in PCL such tables are indeed associated with the 
respective classes).

There is also another perspective to look at this: You cannot simply 
compare a generic function with a plain function. A plain function that 
doesn't do anything interesting is by definition always more efficient 
than anything else. However, generic functions always do something 
interesting - that is, they perform method dispatch. So semantically, 
you can only compare a generic function with a plain function that does 
something similar - i.e., that selects a certain behavior based on the 
types of the arguments it receives. The manual way to perform such 
behavior selection is by way of if/cond/case/typecase forms. So a 
discussion about efficiency boils down to the question of whether your 
own manual if-statements are more efficient than the automatically 
generated ones in generic functions. I would clearly bet on the latter, 
for example because CLOS can take internal implementation details of the 
various types into account that you as a programmer simply don't know about.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: CLOS
Date: 
Message-ID: <5e43mnF361qb5U2@mid.individual.net>
Pascal Costanza wrote:
> D Herring wrote:
> 
>> The CLOS allows multiple dispatch based on (IIRC) almost anything: 
>> base class, subclass, object instance, object contents, and even the 
>> time of day.  This power isn't free; CLOS calls are generally slower 
>> than normal function calls.  C++ trades multiple dispatch (and a 
>> dynamic language) for compiler optimizations (such as vtables).
> 
> Claims about CLOS being slow are highly exaggerated.

...an addendum: What I said in my previous posting only holds for highly 
optimized CLOS implementations. A naive CLOS implementation will of 
course definitely be much slower than plain functions (for example the 
plain Closette implementation in The Art of the Metaobject Protocol, or 
the various versions of Tiny CLOS). But most major CL implementations 
put a lot of effort into performing the kinds of optimizations (or 
similar ones) that I described.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Alex Mizrahi
Subject: Re: CLOS
Date: 
Message-ID: <467ce5e7$0$90268$14726298@news.sunsite.dk>
(message (Hello 'Pascal)
(you :wrote  :on '(Sat, 23 Jun 2007 10:21:12 +0200))
(

 PC> Claims about CLOS being slow are highly exaggerated. It's just that the
 PC> optimization model for generic functions is more complex than vtables.

 PC> that method. No dispatch is necessary at all (which in theory is
 PC> actually better than vtables).

actually, a simple function call via symbol can be compared to vtables in 
C++ -- implementation needs to retrieve symbol-function from symbol, from 
machine language point of view it's actually the same as retrieving function 
pointer via vtable. so, it's very unlikely for CLOS calls to be ever faster 
than C++ calls :).

i think we'd better compare with Python :). Python always uses hash tables 
for slot/method lookup. as you've wrote, CLOS dispatch can be superior to it 
in many cases, even while offering better functionality, like multiple 
dispatch.
and it's not the only case, it appears Python author's approach was to make 
simple implementation, and they didn't care about performance much -- "why 
don't use hash tables for everything?".
OTOH Common Lisp has decades of history behind it, so standard's authors 
knew how to make both simple interface, powerful functionality and make it 
as optimizable as possible.

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"I am everything you want and I am everything you need") 
From: Pascal Costanza
Subject: Re: CLOS
Date: 
Message-ID: <5e48uqF36lrgvU1@mid.individual.net>
Alex Mizrahi wrote:
> (message (Hello 'Pascal)
> (you :wrote  :on '(Sat, 23 Jun 2007 10:21:12 +0200))
> (
> 
>  PC> Claims about CLOS being slow are highly exaggerated. It's just that the
>  PC> optimization model for generic functions is more complex than vtables.
> 
>  PC> that method. No dispatch is necessary at all (which in theory is
>  PC> actually better than vtables).
> 
> actually, a simple function call via symbol can be compared to vtables in 
> C++ -- implementation needs to retrieve symbol-function from symbol, from 
> machine language point of view it's actually the same as retrieving function 
> pointer via vtable. so, it's very unlikely for CLOS calls to be ever faster 
> than C++ calls :).

Normally, function calls in Common Lisp don't go via the symbol. 
(funcall 'foo ...) does an indirection via a symbol, but (funcall #'foo 
...) doesn't. Likewise in CLOS, the "method dispatcher" isn't found via 
the symbol that denotes a generic function, but via an entry in the 
generic function metaobject itself. You don't need a table for that, 
just one indirection. Indirections don't have to cost a lot if they are 
implemented in the right way. Furthermore the jump to the indirection 
entry can be inlined.

You could, for example, reserve a fixed size space for the method 
dispatcher whose code is directly changed whenever a method is added or 
removed. Only if the dispatching code is larger than the reserved space, 
you need to do an actual indirection. Otherwise, the invocation of the 
generic function is just one jump to the method dispatcher (and in the 
specialized cases, to the effective method itself). I believe that this 
is what clisp does, for example.

It's important that generic function dispatch doesn't go through the 
symbol-function of a symbol in the general case because generic 
functions can also be anonymous.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Rainer Joswig
Subject: Re: CLOS
Date: 
Message-ID: <joswig-62F181.12083323062007@news-europe.giganews.com>
In article <·························@news.sunsite.dk>,
 "Alex Mizrahi" <········@users.sourceforge.net> wrote:

> (message (Hello 'Pascal)
> (you :wrote  :on '(Sat, 23 Jun 2007 10:21:12 +0200))
> (
> 
>  PC> Claims about CLOS being slow are highly exaggerated. It's just that the
>  PC> optimization model for generic functions is more complex than vtables.
> 
>  PC> that method. No dispatch is necessary at all (which in theory is
>  PC> actually better than vtables).
> 
> actually, a simple function call via symbol can be compared to vtables in 
> C++ -- implementation needs to retrieve symbol-function from symbol,

Generally that's not true for functions. A function call does not
need to do a symbol lookup in Common Lisp.

For example you have a file with

...

(defun foo (bar) ...)

...

(defun baz ()
  (foo 'bar))

...

The call to foo does not need to do any lookup. The compiler
is allowed to assume that within the file any call of FOO
means the same FOO defined in that file.    

http://www.lispworks.com/documentation/HyperSpec/Body/03_bbc.htm

For local recursive calls this is the same. The call of FOO
in

(defun foo (bar)
   (if ...
       (foo 'bar)
       ...))

does not need to do any lookup of the function FOO.



> from 
> machine language point of view it's actually the same as retrieving function 
> pointer via vtable. so, it's very unlikely for CLOS calls to be ever faster 
> than C++ calls :).

The typical problem here is that one starts to compare apples and
oranges. CLOS generic functions are providing a very different
functionality.

Common Lisp gives you the choice of a simple function construct
that allows many optimisations or a more complex generic
function that allows multiple method implementations with
method-combinations and multi-dispatch. Nevertheless it is
desirable to have fast implementations of CLOS.

> i think we'd better compare with Python :). Python always uses hash tables 
> for slot/method lookup. as you've wrote, CLOS dispatch can be superior to it 
> in many cases, even while offering better functionality, like multiple 
> dispatch.
> and it's not the only case, it appears Python author's approach was to make 
> simple implementation, and they didn't care about performance much -- "why 
> don't use hash tables for everything?".
> OTOH Common Lisp has decades of history behind it, so standard's authors 
> knew how to make both simple interface, powerful functionality and make it 
> as optimizable as possible.
> 
> )
> (With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
> "I am everything you want and I am everything you need")

-- 
http://lispm.dyndns.org
From: Barry Margolin
Subject: Re: CLOS
Date: 
Message-ID: <barmar-58E383.22525722062007@comcast.dca.giganews.com>
In article <························@c77g2000hse.googlegroups.com>,
 ·········@gmail.com wrote:
> Basically my question is, do objects contain references to their
> "member functions"? Presumably you wouldn't have "member" functions
> per se, but it should be clear what I mean. Mostly I'm just curious if
> CLOS "objects" require you to pass around the member functions or not.
> (Of course I'm only talking about cases when you can't just import the
> correct module.)

If you're coming from a C++ background, then perhaps the best way to 
describe this is that it's more like function overloading.  The big 
difference is that function overloading in C++ uses the static type, 
while CLOS generic functions use the dynamic type (like C++ virtual 
functions do).

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Kent M Pitman
Subject: Re: CLOS
Date: 
Message-ID: <uy7ibgynp.fsf@nhplace.com>
·········@gmail.com writes:

> Presumably you wouldn't have "member" functions
> per se, but it should be clear what I mean. Mostly I'm just curious if
> CLOS "objects" require you to pass around the member functions or not.
> (Of course I'm only talking about cases when you can't just import the
> correct module.)

This presumably comes from some something you have to do with another
language. Can you sketch an example of what you're worried about
having to do?  That would probably allow someone to show you how you
do the same thing in Lisp with more clarity.

In general, methods and classes are orthogonal in Lisp.  Methods can
be written on objects without exposing their internals (and, in fact,
can be written on objects for which you do not have access to the
internals, such as primitive types, which don't even have a metaclass
that is guaranteed to allow you access to internals even if you
tried), and ordinary functions can be written that access the
internals of objects [see with-slots].
From: ·········@gmail.com
Subject: Re: CLOS
Date: 
Message-ID: <1182570909.829928.245810@n2g2000hse.googlegroups.com>
On Jun 22, 10:03 pm, Kent M Pitman <······@nhplace.com> wrote:
> ·········@gmail.com writes:
> > Presumably you wouldn't have "member" functions
> > per se, but it should be clear what I mean. Mostly I'm just curious if
> > CLOS "objects" require you to pass around the member functions or not.
> > (Of course I'm only talking about cases when you can't just import the
> > correct module.)
>
> This presumably comes from some something you have to do with another
> language. Can you sketch an example of what you're worried about
> having to do?
Sorry if I misled you. I have no practical reason for asking this
question. The solution is to, of course, pass the method as a
parameter whenever you need it. I was just curious whether I had
misjudged the CLOS.

I do have a practical question that I asked above, though. I'll repeat
it here: how are streams represented in Common Lisp? Do
you need to pass around the stream methods, or is the needed
flexibility embedded in a base set of methods which then dispatch
based on the type? (I realize that streams probably aren't implemented
as classes in CL, but the problem is still the same.)
From: Kent M Pitman
Subject: Re: CLOS
Date: 
Message-ID: <u4pkzi7tm.fsf@nhplace.com>
··········@gmail.com" <·········@gmail.com> writes:

> On Jun 22, 10:03 pm, Kent M Pitman <······@nhplace.com> wrote:
> > ·········@gmail.com writes:
> > > Presumably you wouldn't have "member" functions
> > > per se, but it should be clear what I mean. Mostly I'm just curious if
> > > CLOS "objects" require you to pass around the member functions or not.
> > > (Of course I'm only talking about cases when you can't just import the
> > > correct module.)
> >
> > This presumably comes from some something you have to do with another
> > language. Can you sketch an example of what you're worried about
> > having to do?
> Sorry if I misled you. I have no practical reason for asking this
> question. The solution is to, of course, pass the method as a
> parameter whenever you need it. I was just curious whether I had
> misjudged the CLOS.

There's such a thing as a method, but unless you're doing
metaprogramming, you never actually touch it.  CLOS is a way of
defining programs, but the programs it makes are, in day-to-day use,
just functions.  So your terminology is slightly odd here, and you
might want to get used to just saying "function".

In particular, if you do
  (defmethod foo ((x integer)) (+ x 1))
  (defclass something () ())
  (defmethod foo ((x something)) (random 10))
and you do
  (defmethod bar ((x something))
    (funcall g #'foo x))
you're not passing something's method for foo, because #'foo just
names the generic function.  It happens to be applicable to the something,
but (a) it doesn't know if you're planning on doing:
  (defun g (a b) (funcall a b))
or doing:
  (defun g (a b) (list a (funcall b 7)))
and both will work because the #'foo is applicable to both a something
and an integer.

It's important to understand, too, the above foo method on SOMETHING
is not modifying the class SOMETHING.  The function lives "outboard".
Other than the way updates are done if you redefine something or add a
method, which is clever and which exposes some of the implementation, 
there's not a lot of difference between having done those two defmethods
and having done
 (defun foo (x)
   (typecase x
     (integer (+ x 1))
     (something (random 10))))
That function, as you can clearly see, is not "inside of" either the
SOMETHING class nor the integer class.

> I do have a practical question that I asked above, though. I'll repeat
> it here: how are streams represented in Common Lisp? 

It's not defined by the standard, so it depends on which streams and
which implementations.  There are some commonplace extensions that various
implementations offer that expose the implementation so you can extend it.

> Do you need to pass around the stream methods,

No, but that isn't going to change whether they are or are not standard
classes.  If they are built-in streams, the functions that operate on them
are well-known [read-char, write-char, read-byte, write-byte, force-input,
clear-output, close, etc.] and you don't pass the methods, you just use
the operations on a stream you've received because all streams understand
these operations.  If they are user-defined streams, usually due to these
extension options I mentioned, you still don't pass the methods.  You just
pass the object and assume the caller will access your method through the
package system, so it isn't passed.

> or is the needed
> flexibility embedded in a base set of methods which then dispatch
> based on the type?

A base set of generic functions.  Methods are internal objects that
you don't get your hands on and wouldn't know what arguments to give
even if you did... well, you would if you read the meta-object
protocol.  But my point is that this is not part of every-day
programming of the kind you're asking about.  (You shouldn't be scared
of the meta-object protocol, btw.  It's interesting to learn and offers
some interesting functionality.  But you shouldn't get it confused with
the normal CLOS operations either.)

> (I realize that streams probably aren't implemented
> as classes in CL, but the problem is still the same.)

You probably want to use the word "standard class".  Integers, floats,
pathnames, etc. are all implemented using classes, but the term class is
quite general in CL.  Even structs are classes.  When people say classes
they often mean "standard class".  Structs are made from "structure classes".
Integers are made from the "built-in class" integer.

The problem is indeed the same either way, though, and your question doesn't
make sense but hopefully my answer will help you sort it out.

I'm oversimplifying various things, to keep you on the straight and
narrow for now.  The truth is in CLHS and you're welcome to explore
that when you're up to that level of detail.  Beyond that, you may
enjoy reading about the MOP as well. It's not part of the standard but
is widely implemented, and the book The Art of the Metaobject Protocol
is a fun read.  But it's not recommended as starter material.  Start
with getting grounded on using the basics so you'll be grounded as to
the original purpose of things you expand out into how that original
purpose can be generalized.
From: ·········@gmail.com
Subject: Re: CLOS
Date: 
Message-ID: <1182607454.675268.70640@g4g2000hsf.googlegroups.com>
> > Do you need to pass around the stream methods,
>
> No, but that isn't going to change whether they are or are not standard
> classes.  If they are built-in streams, the functions that operate on them
> are well-known [read-char, write-char, read-byte, write-byte, force-input,
> clear-output, close, etc.] and you don't pass the methods, you just use
> the operations on a stream you've received because all streams understand
> these operations.  If they are user-defined streams, usually due to these
> extension options I mentioned, you still don't pass the methods.  You just
> pass the object and assume the caller will access your method through the
> package system, so it isn't passed.

Ok, thanks, this is mostly what I was looking for. I was just curious
if the CLOS handles my "stream problem" (constrast to the expression
problem) or not.

(I'm not a newbie, if I've misled you. I probably could've looked both
of my questions up, but I wanted to make sure I was right.)
From: Alex Mizrahi
Subject: Re: CLOS
Date: 
Message-ID: <467c7961$0$90271$14726298@news.sunsite.dk>
(message (Hello ··········@gmail.com)
(you :wrote  :on '(Fri, 22 Jun 2007 17:45:07 -0700))
(

 c> I understand that CLOS is generally considered more powerful because
 c> it has multiple dispatch, correct? I'm curious: based on that it seems
 c> unlikely that CLOS implements dispatch using the "standard" vtable
 c> technique. However, I'm not exactly sure if this is the case.

no, certainly vtable is not used.

i've encoutered implementation where for each GF it builds a function 
("discriminating function"), that tells which methods to call for a specific 
type signature. and certainly Lisp can optimize those functions for 
particular cases (no methods, single method, single argument, many 
arguments), compile them into native code, use hashes/caches or whatever..
if some method is added or removed, this function gets invalidated and 
re-created on next invocation.

but note that i'm not a CLOS expert :)

 c> Basically my question is, do objects contain references to their
 c> "member functions"?

no

 c> be clear what I mean. Mostly I'm just curious if CLOS "objects" require
 c> you to pass around the member functions or not. (Of course I'm only
 c> talking about cases when you can't just import the correct module.)

sorry, unable to parse this, but Generic Functions and Objects are almost 
orthogonal.
you can use GF without objects -- dispatch on different types of numbers, 
strings etc.
you can also use Objects without GFs.

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"I am everything you want and I am everything you need") 
From: Pascal Costanza
Subject: Re: CLOS
Date: 
Message-ID: <5e42c1F369856U1@mid.individual.net>
·········@gmail.com wrote:
> Hello. I don't have much experience using Common Lisp, so pardon me if
> this question seems obvious.
> 
> I understand that CLOS is generally considered more powerful because
> it has multiple dispatch, correct? I'm curious: based on that it seems
> unlikely that CLOS implements dispatch using the "standard" vtable
> technique. However, I'm not exactly sure if this is the case.

There is a nice paper that explains how method dispatch works in 
principle in PCL (a somewhat portable implementation of CLOS that is, 
for example, used in CMUCL, GCL and SBCL). You can find it here: 
http://www2.parc.com/csl/groups/sda/publications/papers/Kiczales-Andreas-PCL/for-web.pdf

It also hints at other approaches in a section on related work.

The documentations for the CL implementations that use PCL typically 
have more specific information.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/