Hi,
I have two questions related to CLOS.
+ How can I make sure that all instances of standard-object have an
extra instance variable for my purposes? I have tried to do a defclass
on standard-object both in LispWorks and MCL, and both reject it. I
could write a mixin class and redefine defclass (for example, in a
conduit), but this means that I cannot ensure the addition of that field
to classes that already exist at that point in time. Do I have to live
with this, or are there idioms that I don't know yet? (I am really
interested in adding the field also to classes of built-in and
third-party libraries.)
+ Are there some standard benchmarks for CLOS? I have seen
http://www.chez.com/emarsden/downloads/, but they seem to consist mainly
of microbenchmarks. I would be more interested in simulation of
"real-world" programs that measure net effects of CLOS features.
Background: I would like to tweak slot-value/accessor methods and see
the difference it makes compared to unmodified CLOS. The benchmarks
should be executable on considerably efficient implementations of Common
Lisp, comparable in speed to C++. [1]
Thanks a lot in advance!
Pascal
[1] I know that this kind of efficiency is typical for most Common Lisp
implementations nowadays. It's just an important requirement in my case
that is worth mentioning.
--
Pascal Costanza University of Bonn
···············@web.de Institute of Computer Science III
http://www.pascalcostanza.de R�merstr. 164, D-53117 Bonn (Germany)
From: Joe Marshall
Subject: Re: Tweaking and measuring CLOS
Date:
Message-ID: <lm0ckqfi.fsf@ccs.neu.edu>
Pascal Costanza <········@web.de> writes:
> Hi,
>
> I have two questions related to CLOS.
>
> + How can I make sure that all instances of standard-object have an
> extra instance variable for my purposes? I have tried to do a defclass
> on standard-object both in LispWorks and MCL, and both reject it. I
> could write a mixin class and redefine defclass (for example, in a
> conduit), but this means that I cannot ensure the addition of that
> field to classes that already exist at that point in time. Do I have
> to live with this, or are there idioms that I don't know yet? (I am
> really interested in adding the field also to classes of built-in and
> third-party libraries.)
Doing such a thing would not be easy. You would be relying on CLOS to
retrofit all existing instances of everything (except built-in
classes) with a new slot. But the CLOS MOP is generally written in
CLOS, so it would have to modify itself....
If you had access to the source code you could probably define a new
slot before CLOS has self-bootstrapped, though. It'd be very ugly.
> + Are there some standard benchmarks for CLOS? I have seen
> http://www.chez.com/emarsden/downloads/, but they seem to consist
> mainly of microbenchmarks. I would be more interested in simulation of
> "real-world" programs that measure net effects of CLOS features.
>
>
> Background: I would like to tweak slot-value/accessor methods and see
> the difference it makes compared to unmodified CLOS. The benchmarks
> should be executable on considerably efficient implementations of
> Common Lisp, comparable in speed to C++. [1]
I think that you'd be better served by deriving your own classes. You
could derive two versions, one with and one without modified
slot-value methods. Then you would be comparing apples against
apples.
Joe Marshall wrote:
> Pascal Costanza <········@web.de> writes:
>>Background: I would like to tweak slot-value/accessor methods and see
>>the difference it makes compared to unmodified CLOS. The benchmarks
>>should be executable on considerably efficient implementations of
>>Common Lisp, comparable in speed to C++. [1]
>
>
> I think that you'd be better served by deriving your own classes. You
> could derive two versions, one with and one without modified
> slot-value methods. Then you would be comparing apples against
> apples.
Yes, this sounds like the most feasible approach so far.
Thanks a lot for the various responses.
Pascal
--
Pascal Costanza University of Bonn
···············@web.de Institute of Computer Science III
http://www.pascalcostanza.de R�merstr. 164, D-53117 Bonn (Germany)
Pascal Costanza wrote:
> Joe Marshall wrote:
>
>> Pascal Costanza <········@web.de> writes:
>
>
>>> Background: I would like to tweak slot-value/accessor methods and see
>>> the difference it makes compared to unmodified CLOS. The benchmarks
>>> should be executable on considerably efficient implementations of
>>> Common Lisp, comparable in speed to C++. [1]
>>
>>
>>
>> I think that you'd be better served by deriving your own classes. You
>> could derive two versions, one with and one without modified
>> slot-value methods. Then you would be comparing apples against
>> apples.
>
But mightn't that also be comparing the same apple against itself? If
the portal slot-value gets optimized by /not/ dispatching thru
slot-value-using-class (svuc), and if specializing on svuc for a new
metaclass forces the implementation to abandon its alternate (and fast)
dispatch scheme and /always/ go through svuc, then the mere act of
defining the new SVUC for one particular class/metaclass will whack the
performance of all classes.
So now your new class looks a little faster because you put in some neat
optimization, and the old class (thx to your new class!) is no longer
getting the vendor's optimizations of slot-value.
I guess the trick is to cook up a little benchmark and run it before
doing any new clos hacking. save the results. then try your
optimization. then slave mightily to get back to the performance the
vendor had achieved. i doubt you can.
Google up Dave Bakhash's experiment along these lines, simulcast on
c.l.l. A couple of years ago, I think. I think he concluded there was no
way to come anywhere near the optimization vendors can pull off with all
their expertise and access to/control over internals.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore
From: Joe Marshall
Subject: Re: Tweaking and measuring CLOS
Date:
Message-ID: <1y22llr4.fsf@ccs.neu.edu>
Kenny Tilton <·······@nyc.rr.com> writes:
> But mightn't that also be comparing the same apple against itself?
I was assuming that you would create a parallel type hierarchy, one
which derived from the standard classes and one that derived from your
specialized classes. Otherwise the type hierarchies would be
identical.
Joe Marshall wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
>
>>But mightn't that also be comparing the same apple against itself?
>
>
> I was assuming that you would create a parallel type hierarchy, one
> which derived from the standard classes and one that derived from your
> specialized classes. Otherwise the type hierarchies would be
> identical.
Sure, diff hierarchies, I see that. I am just saying that once you
compile a new method on slot-value-using-class for one hierarchy the
optimization is whacked for all. Or at least it might me, can't say I
worried about that when doing my explorations into the cost of
specializing svuc. I am just giving Pascal a head's up on this.
ie, take a benchmark of the untampered-with hierarchy before anything
else. make sure a new, svuc-powered class does not impact the first.
mind you, not sure at this point they even need to play with svuc. just
offering this fwiw.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore
From: Joe Marshall
Subject: Re: Tweaking and measuring CLOS
Date:
Message-ID: <ptplk1pe.fsf@ccs.neu.edu>
Kenny Tilton <·······@nyc.rr.com> writes:
> Joe Marshall wrote:
> > I was assuming that you would create a parallel type hierarchy, one
> > which derived from the standard classes and one that derived from your
> > specialized classes. Otherwise the type hierarchies would be
> > identical.
>
> Sure, diff hierarchies, I see that. I am just saying that once you
> compile a new method on slot-value-using-class for one hierarchy the
> optimization is whacked for all.
I suppose it would depend on the implementation, of course. I was
assuming that adding methods to SVUC wouldn't affect the regular
classes (I *think* that CLOS is allowed to bypass SVUC in some
circumstances).
Joe Marshall <···@ccs.neu.edu> writes:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
> > Joe Marshall wrote:
> > > I was assuming that you would create a parallel type hierarchy, one
> > > which derived from the standard classes and one that derived from your
> > > specialized classes. Otherwise the type hierarchies would be
> > > identical.
> >
> > Sure, diff hierarchies, I see that. I am just saying that once you
> > compile a new method on slot-value-using-class for one hierarchy the
> > optimization is whacked for all.
>
> I suppose it would depend on the implementation, of course. I was
> assuming that adding methods to SVUC wouldn't affect the regular
> classes (I *think* that CLOS is allowed to bypass SVUC in some
> circumstances).
As far as PCL is concerned, only applicable SVUC methods should count.
I don't think SVUC may be bypassed, though. I can't find that in
AMOP.
From: Tim Bradshaw
Subject: Re: Tweaking and measuring CLOS
Date:
Message-ID: <ey3isvajtat.fsf@cley.com>
* Gerd Moellmann wrote:
> As far as PCL is concerned, only applicable SVUC methods should count.
> I don't think SVUC may be bypassed, though. I can't find that in
> AMOP.
Well, an implementation can not call it if it can prove that there are
no non-implementation-defined applicable methods for it.
--tim
Tim Bradshaw <···@cley.com> writes:
> * Gerd Moellmann wrote:
>
> > As far as PCL is concerned, only applicable SVUC methods should count.
> > I don't think SVUC may be bypassed, though. I can't find that in
> > AMOP.
>
> Well, an implementation can not call it if it can prove that there are
> no non-implementation-defined applicable methods for it.
Of course; that's what PCL does.
In article <················@nyc.rr.com>,
Kenny Tilton <·······@nyc.rr.com> wrote:
> Sure, diff hierarchies, I see that. I am just saying that once you
> compile a new method on slot-value-using-class for one hierarchy the
> optimization is whacked for all. Or at least it might me, can't say I
> worried about that when doing my explorations into the cost of
> specializing svuc. I am just giving Pascal a head's up on this.
Yes, I have got it and it also seems to make sense. Thanks for this hint.
Pascal
--
"If I could explain it, I wouldn't be able to do it."
A.M.McKenzie
Kenny Tilton wrote:
>
>
>> Joe Marshall wrote:
>>> I think that you'd be better served by deriving your own classes. You
>>> could derive two versions, one with and one without modified
>>> slot-value methods. Then you would be comparing apples against
>>> apples.
>>
>>
>
> But mightn't that also be comparing the same apple against itself? If
> the portal slot-value gets optimized by /not/ dispatching thru
> slot-value-using-class (svuc), and if specializing on svuc for a new
> metaclass forces the implementation to abandon its alternate (and fast)
> dispatch scheme and /always/ go through svuc, then the mere act of
> defining the new SVUC for one particular class/metaclass will whack the
> performance of all classes.
Perhaps it's time to give some more information on what I actually want
to do.
For my PhD, I have developed a language extension for Java that allows
you to replace an object by a different object without affecting the
known references to the old object (so they point to the new object).
This is somewhat like Smalltalk's become: operator. [1]
Essentially you implement this by including another level of
indirection. So for example when performing a make-instance you don't
return the object itself, but a proxy object. Then you can replace an
object by just changing the reference inside the proxy. (Nothing very
breathtaking here.)
In such a scheme, sv or svuc needs to go via the proxy reference in
order to get to the actual object. This sounds like a serious
performance penalty. Now, in our experimental implementation we have
taken the route that the indirection reference is not stored in a proxy
object, but in the actual objects themselves. This means that by
default, the proxy reference points to itself (or better, to the
surrounding object), like follows.
+---------------+
| |
V |
(object |
indirection --+
fields
...)
Now, sv/svuc still need to go via the indirection. However, in most
cases the surrounding area is probably already in the CPU cache, so the
performance penalty isn't that high. Our experiments indicate an average
penalty of just 5%.
The drawback of our experiments is that they are based on a purely
interpreted JVM. What I am now trying to do is to do the experiments
with a "proper" language. ;) (Unfortunately, it's likely that the
performance penalty is much higher in a compiled language. But that's
exactly what I want to find out.)
It's best to measure these things with benchmarks that simulate
real-world programs. Microbenchmarks usually give you a wrong picture.
That's why I hoped for a kind of standard CLOS benchmark suite.
(For example, a performance penalty for method dispatch of about, say,
20% doesn't do any serious harm, because usually programs only spend 20%
of their time in method dispatching code. So this would amount to just
5% in total.)
If you are interested in more details about the language design, see the
Gilgul section on my homepage. (totally unrelated to Lisp, though)
Pascal
[1] I have started my PhD long time before I have learnt about Common
Lisp, so forgive me that I had used Java. ;)
--
Pascal Costanza University of Bonn
···············@web.de Institute of Computer Science III
http://www.pascalcostanza.de R�merstr. 164, D-53117 Bonn (Germany)
Pascal Costanza <········@web.de> writes:
> For my PhD, I have developed a language extension for Java that
> allows you to replace an object by a different object without
> affecting the known references to the old object (so they point to
> the new object). This is somewhat like Smalltalk's become:
> operator.
I'm not quite sure I understand what you mean, but are you sure this
isn't already a part of CLOS? Any standard-object is basically only an
identity, whose class or value(s) may be changed at any time. I don't
know what else about an object you'd want to change so as to make it
a "different object".
--
Frode Vatvedt Fjeld
Frode Vatvedt Fjeld wrote:
> Pascal Costanza <········@web.de> writes:
>
>
>>For my PhD, I have developed a language extension for Java that
>>allows you to replace an object by a different object without
>>affecting the known references to the old object (so they point to
>>the new object). This is somewhat like Smalltalk's become:
>>operator.
>
>
> I'm not quite sure I understand what you mean, but are you sure this
> isn't already a part of CLOS?
Jumping in if I might, since the end goal is a Java hack, the
wonderfulness of CLOS may not be an alternative.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore
Kenny Tilton <·······@nyc.rr.com> writes:
> Jumping in if I might, since the end goal is a Java hack, the
> wonderfulness of CLOS may not be an alternative.
Oh sorry, guess I didn't pay close enough attention, I was under the
impression he wanted to move the Java hack to CLOS.
--
Frode Vatvedt Fjeld
In article <··············@vserver.cs.uit.no>,
Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
> > Jumping in if I might, since the end goal is a Java hack, the
> > wonderfulness of CLOS may not be an alternative.
>
> Oh sorry, guess I didn't pay close enough attention, I was under the
> impression he wanted to move the Java hack to CLOS.
No, I only want to simulate it in CLOS in order to perform some
realistic benchmarks that I can't do in our interpreter-based
implementation.
Pascal
--
"If I could explain it, I wouldn't be able to do it."
A.M.McKenzie
In article <··············@vserver.cs.uit.no>,
Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
> Pascal Costanza <········@web.de> writes:
>
> > For my PhD, I have developed a language extension for Java that
> > allows you to replace an object by a different object without
> > affecting the known references to the old object (so they point to
> > the new object). This is somewhat like Smalltalk's become:
> > operator.
>
> I'm not quite sure I understand what you mean, but are you sure this
> isn't already a part of CLOS? Any standard-object is basically only an
> identity, whose class or value(s) may be changed at any time. I don't
> know what else about an object you'd want to change so as to make it
> a "different object".
I am aware of the CLOS feature for changing the class of an object. What
I am proposing is slightly different.
Instead of (change-class obj1 'other-class), you can say "obj1 become
obj2" in Smalltalk, or "obj1 #= obj2" in my Java dialect. In order to
simulate change-class you can say "obj1 #= new OtherClass()". (This is
not completely the same, though.)
Although these things are more or less functionally equivalent, they
correspond to different mental models. Changing the class of an object
is not the same as replacing an object. For example, (change-class
george-w-bush 'intelligent-person) is something different than
"georgeWBush #= hilaryClinton".
(As a sidenote, Smalltalk's become: doesn't have clean semantics. The
contribution of my work is that I provide clean semantics for a
replacement operator. It isn't just a Java hack, but I have checked very
carefully that my approach is original and doesn't already exist in any
documented language. See my papers for more information.)
Pascal
--
"If I could explain it, I wouldn't be able to do it."
A.M.McKenzie
Pascal Costanza <········@web.de> writes:
> I am aware of the CLOS feature for changing the class of an
> object. What I am proposing is slightly different.
>
> Instead of (change-class obj1 'other-class), you can say "obj1
> become obj2" in Smalltalk, or "obj1 #= obj2" in my Java dialect. In
> order to simulate change-class you can say "obj1 #= new
> OtherClass()". (This is not completely the same, though.)
I think it'd be more like "obj1 = copy obj2", where you copy obj2's
class pointer and slot storage.
So what you want to achieve is that after "obj1 #= obj2" you want
changes in obj1 to be reflected in obj2, and the other way around? I
looked briefly at one of your papers and the indirect pointer
scheme. I don't think you can easily achieve exactly this without
modifying the basic internals of an implementation. It might be
interesting to experiment with having two or more standard-objects
share slot-storage, though. I.e to not copy obj2's slot-store, but to
copy the reference (pointer) to obj2's slot-storage into obj1. This
would almost achieve the goal as stated above, with the exception that
if one were to change the class of either obj1 or obj2, this wouldn't
be reflected in the other, and probably break their sameness
relationship, unless some special protocol for change-class is
devised.
--
Frode Vatvedt Fjeld
In article <··············@vserver.cs.uit.no>,
Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
> So what you want to achieve is that after "obj1 #= obj2" you want
> changes in obj1 to be reflected in obj2, and the other way around?
Yes, roughly. Thanks for the ideas.
I understand by now that it wouldn't be easy to simulate my approach
with CLOS, at least not if I were to modify standard-object. However,
since there doesn't seem to be standard CLOS benchmarks that simulate
large programs, I need to write the benchmarks on my own as well. So I
can avoid the difficulties of hacking standard-object...
Pascal
--
"If I could explain it, I wouldn't be able to do it."
A.M.McKenzie
Pascal Costanza <········@web.de> wrote in message news:<······························@news.netcologne.de>...
> In article <··············@vserver.cs.uit.no>,
> Frode Vatvedt Fjeld <······@cs.uit.no> wrote:
>
> > Pascal Costanza <········@web.de> writes:
> >
> > > For my PhD, I have developed a language extension for Java that
> > > allows you to replace an object by a different object without
> > > affecting the known references to the old object (so they point to
> > > the new object). This is somewhat like Smalltalk's become:
> > > operator.
> >
> > I'm not quite sure I understand what you mean, but are you sure this
> > isn't already a part of CLOS? Any standard-object is basically only an
> > identity, whose class or value(s) may be changed at any time. I don't
> > know what else about an object you'd want to change so as to make it
> > a "different object".
>
> I am aware of the CLOS feature for changing the class of an object. What
> I am proposing is slightly different.
>
> Instead of (change-class obj1 'other-class), you can say "obj1 become
> obj2" in Smalltalk, or "obj1 #= obj2" in my Java dialect. In order to
> simulate change-class you can say "obj1 #= new OtherClass()". (This is
> not completely the same, though.)
This smells like what C++ programmers call ``pimpl'': pointer to
implementation.
There is some wrapper object which contains a reference to the real
one and delegates method to it.
An object could ``become'' another one if you replace the pointer to
implementation to a different backing object.
To complete the ``illusion'', overload the assignment operator.
class SomeObjectImplementation; // base class of implementations
class SomeObject {
private:
SmartPointer<SomeObjectImplementation> pImpl;
public:
void SomeMethod() { pImpl->SomeMethod(); } // delegation
void Become(const SomeObject &other)
{
pImpl = other.pImpl;
}
void operator = (const SomeObject &other) // sugar
{
Become(other);
}
};
The ``design pattern'' called State involves a context object with a
pointer to a state object. The state object is replaced in order to
represent state changes in the overall aggregate of the two.
What makes your ideas original?
In article <····························@posting.google.com>,
···@ashi.footprints.net (Kaz Kylheku) wrote:
> This smells like what C++ programmers call ``pimpl'': pointer to
> implementation.
>
> There is some wrapper object which contains a reference to the real
> one and delegates method to it.
[...]
Yes, this is similar.
> The ``design pattern'' called State involves a context object with a
> pointer to a state object. The state object is replaced in order to
> represent state changes in the overall aggregate of the two.
Again yes, and there are also Strategy, Decorator and various Proxy
patterns that do similar things.
> What makes your ideas original?
I can answer this question on two levels.
1. Pragmatic advantages
In all these patterns and idioms you have to anticipate that you want to
replace objects at some stage. If you haven't prepared your classes for
such replacements you have a hard time to refactor them.
Common Lisp's change-class, Smalltalk's become: and my referent
assignment operator (#=) can be applied in unanticipated contexts, and
furthermore even at runtime.
Furthermore, I claim that for certain situations my referent assignment
operator offers a simpler mental model than both change-class and
become:. change-class and #= (but probably not become:) also help to
solve the object identity problem that is mentioned in the description
of the Decorator pattern by Gamma et al. (Common Lisp's standard method
combinations also solve this problem, but on a different level.)
(As a sidenote, you really don't want to override the assignment
operator (=) in your example, at least not in the general case.
Assignment to a particular variable usually doesn't affect other
variables, whereas the referent assignment does. I think that this is an
important distinction.)
2. Conceptual difference
At the heart of my thesis lies a new conceptual model for what used to
be object identity. Object identity is generally used for two different
purposes, reference and comparison. In my approach (called Gilgul),
these two uses are strictly separated; so to speak, the concept of
object identity doesn't exist anymore in a strict sense. So in Gilgul,
it's strictly forbidden to compare references, but you can only compare
so-called comparands. In turn, comparands cannot be used for
referencing. This allows me to introduce referent assignment and
comparand assignment that manipulate references and comparands without
affecting each other. Referent assignment and comparand assignment can
thus be defined in semantically clean ways and I can avoid the
conceptual problems that Smalltalk's become: has.
This is a very rough summary. Please see my papers in the Gilgul section
of my website at http://www.pascalcostanza.de for more details.
Pascal
--
"If I could explain it, I wouldn't be able to do it."
A.M.McKenzie
On Thu, 20 Feb 2003 18:08:26 +0100, Pascal Costanza <········@web.de>
wrote:
> For my PhD, I have developed a language extension for Java that allows
> you to replace an object by a different object without affecting the
> known references to the old object (so they point to the new object).
[...]
> [1] I have started my PhD long time before I have learnt about Common
> Lisp, so forgive me that I had used Java. ;)
Never mind. I just thought your advisor was Prof. Greenspun :)
Paolo
--
Paolo Amoroso <·······@mclink.it>
In article <····························@4ax.com>,
Paolo Amoroso <·······@mclink.it> wrote:
> > [1] I have started my PhD long time before I have learnt about Common
> > Lisp, so forgive me that I had used Java. ;)
>
> Never mind. I just thought your advisor was Prof. Greenspun :)
:-))
--
"If I could explain it, I wouldn't be able to do it."
A.M.McKenzie
Pascal Costanza wrote:
> Hi,
>
> I have two questions related to CLOS.
>
> + How can I make sure that all instances of standard-object have an
> extra instance variable for my purposes? I have tried to do a defclass
> on standard-object both in LispWorks and MCL, and both reject it.
I suppose where you have a MOP you can get at there might (might!) be a
way to intervene with an around method on one of the mop functions that
computes the slot definitions for a class... but you mentioned MCL which
does not support much of the MOP.
This is a strange requirement insofar as standard-object is what
standard-object is, yer supposed to be subclassing it, not hacking it,
but you know all that. :)
> Background: I would like to tweak slot-value/accessor methods and see
> the difference it makes compared to unmodified CLOS. The benchmarks
> should be executable on considerably efficient implementations of Common
> Lisp, comparable in speed to C++. [1]
If the CLOS implementation is fast it probably optimizes slot access
heavily. A really amateurish benchmark I did suggested a 30% hit because
my Cells implementation was meta-classed based and included specializing
slot-value-using-class. Not sure what yer gonna do that will beat the
30% optimization. And be careful testing. Even a pure class gets
accessed slower if any specialization is done on SVUC.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
the bath water is cold." -- Lorraine Lee Cudmore
Pascal Costanza wrote:
> Hi,
>
> I have two questions related to CLOS.
>
> + How can I make sure that all instances of standard-object have an
> extra instance variable for my purposes? I have tried to do a defclass
> on standard-object both in LispWorks and MCL, and both reject it. I
> could write a mixin class and redefine defclass (for example, in a
> conduit), but this means that I cannot ensure the addition of that field
> to classes that already exist at that point in time. Do I have to live
> with this, or are there idioms that I don't know yet? (I am really
> interested in adding the field also to classes of built-in and
> third-party libraries.)
Why not just making a EQ hash-table and using that to "annotate" all objects
you want?
If that would be a speed problem you could use the table as a fallback
solution for objects that do not have such a slot.
ciao,
Jochen
Jochen Schmidt <···@dataheaven.de> writes:
> Pascal Costanza wrote:
>
> > Hi,
> >
> > I have two questions related to CLOS.
> >
> > + How can I make sure that all instances of standard-object have an
> > extra instance variable for my purposes? I have tried to do a defclass
> > on standard-object both in LispWorks and MCL, and both reject it. I
> > could write a mixin class and redefine defclass (for example, in a
> > conduit), but this means that I cannot ensure the addition of that field
> > to classes that already exist at that point in time. Do I have to live
> > with this, or are there idioms that I don't know yet? (I am really
> > interested in adding the field also to classes of built-in and
> > third-party libraries.)
>
> Why not just making a EQ hash-table and using that to "annotate" all objects
> you want?
>
> If that would be a speed problem you could use the table as a fallback
> solution for objects that do not have such a slot.
You might even be able to combine this with the standard
generic functions slot-missing/slot-unbound... not sure, as I haven't
been able to get these two to do what I want to :-(
--
Raymond Wiker Mail: ·············@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
Try FAST Search: http://alltheweb.com/
Raymond Wiker <·············@fast.no> writes:
> Jochen Schmidt <···@dataheaven.de> writes:
>
> > Why not just making a EQ hash-table and using that to "annotate" all objects
> > you want?
> >
> > If that would be a speed problem you could use the table as a fallback
> > solution for objects that do not have such a slot.
>
> You might even be able to combine this with the standard
> generic functions slot-missing/slot-unbound... not sure, as I haven't
> been able to get these two to do what I want to :-(
>
How about something like this ?
(let ((foo-attributes (make-hash-table :test #'eq))
(unbound (gensym)))
(defmethod slot-missing (class object (slot-name (eql 'foo)) operation
&optional new-value)
(case operation
(lisp:setf (setf (gethash object foo-attributes) new-value))
(lisp:slot-boundp (not (eq (gethash object foo-attributes unbound)
unbound)))
(lisp:slot-makunbound (setf (gethash object foo-attributes) unbound))
;; or (remhash object foo-attributes)
(lisp:slot-value (let ((value (gethash object foo-attributes unbound)))
(if (eq value unbound)
(slot-unbound class object slot-name)
value))))))
My question is if you need to make a method for slot-unbound as well
or if it is ok to call slot-unbound with a slot-name that does not
exist in the class? The spesification says that slot-value should not
be called at all by programmers but in this situation it looks very
natural.
The next step would now be to change this into a macro that gets foo
as a parameter.
Oluf
Asle Olufsen <···@skoyern.nextra.no> writes:
> Raymond Wiker <·············@fast.no> writes:
>
> > Jochen Schmidt <···@dataheaven.de> writes:
> >
> > > Why not just making a EQ hash-table and using that to "annotate" all objects
> > > you want?
> > >
> > > If that would be a speed problem you could use the table as a fallback
> > > solution for objects that do not have such a slot.
> >
> > You might even be able to combine this with the standard
> > generic functions slot-missing/slot-unbound... not sure, as I haven't
> > been able to get these two to do what I want to :-(
> >
>
> How about something like this ?
>
> (let ((foo-attributes (make-hash-table :test #'eq))
> (unbound (gensym)))
>
> (defmethod slot-missing (class object (slot-name (eql 'foo)) operation
> &optional new-value)
Yes, very much like it :-)
In my experiments, I tried to specialize on class, but
couldn't get that to work. The reason that I wanted to specialize on
class, was that I had a class hierarchy that contained a hash map (or
alist, or whatever) for holding 'additional' slots. The reason for
that, again, was that I was working on compiling Python into Common
Lisp, and the Python object model has something like this built-in.
--
Raymond Wiker Mail: ·············@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60
Try FAST Search: http://alltheweb.com/