Hi,
I want to write a generic function which will get executed when the
metaclass of one of the objects (passed as a parameter) is a specific class.
For example:
(defclass my-metaclass (standard-class)
())
(defclass my-class-a ()
()
(:metaclass my-metaclass))
(defclass my-class-b ()
()
(:metaclass my-metaclass))
Now, I want to write a generic method which would run when the object
passed to it is either of my-class-a or my-class-b or any other class
whose metaclass is my-metaclass.
Is this possible without having an intermediary class (my-metaobject,
for example) which would be a base class for both my-class-a and
my-class-b. And the generic method would actually specialize on the
class my-metaobject instead of the metaclass my-metaclass!
What a confusion :-)
I'm using Allegro Lisp (if that matters).
Thanks,
Saurabh.
Saurabh Nanda <············@gmail.com> wrote:
> I want to write a generic function which will get executed when the
> metaclass of one of the objects (passed as a parameter) is a specific
> class.
>
> For example:
>
> (defclass my-metaclass (standard-class)
> ())
>
> (defclass my-class-a ()
> ()
> (:metaclass my-metaclass))
>
> (defclass my-class-b ()
> ()
> (:metaclass my-metaclass))
>
> Now, I want to write a generic method which would run when the object passed
> to it is either of my-class-a or my-class-b or any other class whose metaclass
> is my-metaclass.
>
> Is this possible without having an intermediary class (my-metaobject, for
> example) which would be a base class for both my-class-a and my-class-b. And
> the generic method would actually specialize on the class my-metaobject
> instead of the metaclass my-metaclass!
So you want some kind of a metaclass-eq specializer right ? I'm
not aware of the existence of such a beast (down one meta level though,
SBCL has internal-only support for class-eq specializers).
--
Didier Verna, ······@lrde.epita.fr, http://www.lrde.epita.fr/~didier
EPITA / LRDE, 14-16 rue Voltaire Tel.+33 (1) 44 08 01 85
94276 Le Kremlin-Bic�tre, France Fax.+33 (1) 53 14 59 22 ······@xemacs.org
Saurabh Nanda wrote:
> Hi,
>
> I want to write a generic function which will get executed when the
> metaclass of one of the objects (passed as a parameter) is a specific
> class.
>
> For example:
>
> (defclass my-metaclass (standard-class)
> ())
>
> (defclass my-class-a ()
> ()
> (:metaclass my-metaclass))
>
> (defclass my-class-b ()
> ()
> (:metaclass my-metaclass))
>
> Now, I want to write a generic method which would run when the object
> passed to it is either of my-class-a or my-class-b or any other class
> whose metaclass is my-metaclass.
>
> Is this possible without having an intermediary class (my-metaobject,
> for example) which would be a base class for both my-class-a and
> my-class-b. And the generic method would actually specialize on the
> class my-metaobject instead of the metaclass my-metaclass!
If this is the only reason for having this metaclass, then it's probably
not a good idea to have this metaclass at all. You can achieve the same
effect with a plain old mixin class. Just define a class
my-default-object (or so) that other classes can add to their list of
direct superclasses. The advantage is that you don't even have to worry
about inheritance anymore.
If there are additional reasons for this metaclass, I would use the same
approach still, but just make sure that the metaclass ensures that the
new default object class is added automatically. This is one of the
standard idioms of the CLOS MOP.
It may be possible to tweak compute-applicable-methods-using-classes and
compute-applicable-methods in :around methods in a way such that the
methods which are not applicable according to your desired semantics are
filtered out. However, generic function invocation is the part of the
CLOS MOP which is least well supported across CL implementations, so
your code would be rather non-portable. The first approach above is
fully portable given only ANSI CL, and the second approach is portable
across all CL implementations that support the CLOS MOP that I am aware of.
> I'm using Allegro Lisp (if that matters).
Allegro Common Lisp, for example, doesn't invoke
compute-applicable-methods-using-class and compute-applicable-methods at
all in its default discriminating function implementation, to the best
of my knowledge. So the third approach above would not be feasible here.
(Unless you implement a new discriminating function completely from
scratch, but that's not straightforward, to say the least. ;)
I hope this helps,
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/
Pascal Costanza wrote:
> Allegro Common Lisp, for example, doesn't invoke
> compute-applicable-methods-using-class and compute-applicable-methods at
> all in its default discriminating function implementation, to the best
> of my knowledge.
The name of the specified function is
compute-applicable-methods-using-classES. I believe the
ACL implementation does call these two functions when there have been
nonstandard methods defined on the metaclasses. Otherwise there is no
requirement to call these functions if the implementation does something
equivalent to the specified bahavior of these functions. This is one
way of dealing with the metacircularity uglies of CLOS, and this freedom
is a general principle of ANSI CL.
If you have evidence that ACl is not conforming, let me know and I'll
look into it deeper. But cl:trace is not your friend when studying how
code was compiled...
Steven Haflich wrote:
> Pascal Costanza wrote:
>> Allegro Common Lisp, for example, doesn't invoke
>> compute-applicable-methods-using-class and compute-applicable-methods
>> at all in its default discriminating function implementation, to the
>> best of my knowledge.
>
> The name of the specified function is
> compute-applicable-methods-using-classES.
Correct.
> I believe the
> ACL implementation does call these two functions when there have been
> nonstandard methods defined on the metaclasses.
To the best of my knowledge, it doesn't.
> Otherwise there is no
> requirement to call these functions if the implementation does something
> equivalent to the specified bahavior of these functions. This is one
> way of dealing with the metacircularity uglies of CLOS, and this freedom
> is a general principle of ANSI CL.
Yes, I know. That's not the case I am referring to.
> If you have evidence that ACl is not conforming, let me know and I'll
> look into it deeper. But cl:trace is not your friend when studying how
> code was compiled...
I have a test case in the MOP Feature Tests suite at the Closer project.
I will send it to you...
Thanks for your response,
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/