From: Andrew Lawson
Subject: Metaclass persistence in subclasses
Date: 
Message-ID: <es70r6$kbv$1@registered.motzarella.org>
Hello all
	I'm taking my first steps in MOP programming as I need a group of 
classes that signal when their slots are modified. I came up with the 
code below. This is Lispworks so the slot arg is the slot name.

(defclass signal-class (standard-class)
  ())

(defmethod (setf slot-value-using-class) (new-value
                                               (class signal-class)
                                               obj
                                               slot)
  (format nil "~a-CHANGED" slot)
  (call-next-method))

Then when I create a class that uses it it works fine

(defclass test-class ()
	((test-slot))
	(:metaclass signal-class))

If I now subclass test-class I get an error that test class is an 
invalid superclass as the metaclass of test-subclass is standard-class.

(defclass test-subclass (test-class)
   	())

So the question is, have I missed something in my metaclass definition, 
or if not how do i make a superclass's metaclass persist to its children

	Andrew

From: Tayssir John Gabbour
Subject: Re: Metaclass persistence in subclasses
Date: 
Message-ID: <1172774317.605146.206650@h3g2000cwc.googlegroups.com>
On Mar 1, 6:00 pm, Andrew Lawson <····@kerridge.com> wrote:
> Hello all
>         I'm taking my first steps in MOP programming as I need a group of
> classes that signal when their slots are modified. I came up with the
> code below. This is Lispworks so the slot arg is the slot name.
>
> So the question is, have I missed something in my metaclass definition,
> or if not how do i make a superclass's metaclass persist to its children

Well, I pretty much never use the MOP, but given that caveat, three
things strike me:

   * (format nil ...) should probably be changed to (format t ...)

   * Define methods on validate-superclass.

   * You probably want a method like:

     (defmethod (setf slot-value-using-class) (new-value
                                               (class standard-class)
                                               (obj test-class)
                                               slot)
       (format t "~a-CHANGED 2" slot)
       (call-next-method))


I hope someone corrects me if I'm mistaken...


Tayssir
From: Tayssir John Gabbour
Subject: Re: Metaclass persistence in subclasses
Date: 
Message-ID: <1172775087.069162.242800@h3g2000cwc.googlegroups.com>
On Mar 1, 7:38 pm, "Tayssir John Gabbour"
<············@googlemail.com> wrote:
> On Mar 1, 6:00 pm, Andrew Lawson <····@kerridge.com> wrote:
>
> > Hello all
> >         I'm taking my first steps in MOP programming as I need a group of
> > classes that signal when their slots are modified. I came up with the
> > code below. This is Lispworks so the slot arg is the slot name.
>
> > So the question is, have I missed something in my metaclass definition,
> > or if not how do i make a superclass's metaclass persist to its children

Umm, I misread. Anything wrong with just specifying the metaclass for
your subclass?

Tayssir
From: Ken Tilton
Subject: Re: Metaclass persistence in subclasses
Date: 
Message-ID: <YqFFh.18$5b1.13@newsfe12.lga>
Tayssir John Gabbour wrote:
> On Mar 1, 7:38 pm, "Tayssir John Gabbour"
> <············@googlemail.com> wrote:
> 
>>On Mar 1, 6:00 pm, Andrew Lawson <····@kerridge.com> wrote:
>>
>>
>>>Hello all
>>>        I'm taking my first steps in MOP programming as I need a group of
>>>classes that signal when their slots are modified. I came up with the
>>>code below. This is Lispworks so the slot arg is the slot name.
>>
>>>So the question is, have I missed something in my metaclass definition,
>>>or if not how do i make a superclass's metaclass persist to its children
> 
> 
> Umm, I misread. Anything wrong with just specifying the metaclass for
> your subclass?

Yes. It makes manifest that he chose the wrong tool for the job, cuz, 
now he has to add that to every subclass, where GFs would Just Work. But 
  that would not do, we need a machine that goes Ping!

kzo

-- 
Well, I've wrestled with reality for 35 years, Doctor, and
I'm happy to state I finally won out over it.
                                   -- Elwood P. Dowd

In this world, you must be oh so smart or oh so pleasant.
                                   -- Elwood's Mom
From: Andrew Lawson
Subject: Re: Metaclass persistence in subclasses
Date: 
Message-ID: <es7bi2$rd4$1@registered.motzarella.org>
On 2007-03-01 19:51:27 +0100, "Tayssir John Gabbour" 
<············@googlemail.com> said:

> On Mar 1, 7:38 pm, "Tayssir John Gabbour"
> <············@googlemail.com> wrote:
>> On Mar 1, 6:00 pm, Andrew Lawson <····@kerridge.com> wrote:
>> 
>>> Hello all
>>> I'm taking my first steps in MOP programming as I need a group of
>>> classes that signal when their slots are modified. I came up with the
>>> code below. This is Lispworks so the slot arg is the slot name.
>> 
>>> So the question is, have I missed something in my metaclass definition,
>>> or if not how do i make a superclass's metaclass persist to its children
> 
> Umm, I misread. Anything wrong with just specifying the metaclass for
> your subclass?

Laziness ... but as it is it's one line per class, I'll cope :)

	Andrew
From: Ken Tilton
Subject: Re: Metaclass persistence in subclasses
Date: 
Message-ID: <62EFh.7$OI.6@newsfe12.lga>
Andrew Lawson wrote:
> Hello all
>     I'm taking my first steps in MOP programming as I need a group of 
> classes that signal when their slots are modified.

Bzzt! That does not justify the MOP. I mean, it is fine if you want to 
use the MOP just to use the MOP, I am just objecting to the causal 
relation declared by "as".

Write your own writer methods. Use macrology to avoid the repetitive 
typing. Or use Cells. Or download Cells and rip off the defmodel macro, 
which expands into defclass and more.

kt

ps. Specializing SVUC just /kills/ a nice optimization thereof by ACL. k

-- 
Well, I've wrestled with reality for 35 years, Doctor, and
I'm happy to state I finally won out over it.
                                   -- Elwood P. Dowd

In this world, you must be oh so smart or oh so pleasant.
                                   -- Elwood's Mom
From: Andrew Lawson
Subject: Re: Metaclass persistence in subclasses
Date: 
Message-ID: <es72rg$kbv$2@registered.motzarella.org>
On 2007-03-01 18:27:30 +0100, Ken Tilton <·········@gmail.com> said:

> 
> 
> Andrew Lawson wrote:
>> Hello all
>>     I'm taking my first steps in MOP programming as I need a group of 
>> classes that signal when their slots are modified.
> 
> Bzzt! That does not justify the MOP. I mean, it is fine if you want to 
> use the MOP just to use the MOP, I am just objecting to the causal 
> relation declared by "as".

Let's just say I'm using it for the sake of using it, were I to admit 
to say, linking widgets and data you'd probably have harsher things to 
say :D But I really would like to know because in my case I think it is 
the cleanest solution to my problem.

> Write your own writer methods. Use macrology to avoid the repetitive 
> typing. Or use Cells. Or download Cells and rip off the defmodel macro, 
> which expands into defclass and more.

I don't want to write writer methods, that's the point, neither do i 
want to install another library, no matter how life-changing an 
experience that would be. Should I find I've driven up a one way creek 
I'll be the first to return and admit you were right all along and 
start wearing my Cells t-shirt

> ps. Specializing SVUC just /kills/ a nice optimization thereof by ACL. k

Speed is guaranteed not an issue here.

	cheers

		Andrew
From: Ken Tilton
Subject: Re: Metaclass persistence in subclasses
Date: 
Message-ID: <eBEFh.8$OI.3@newsfe12.lga>
Andrew Lawson wrote:
> Hello all
>     I'm taking my first steps in MOP programming as I need a group of 
> classes that signal when their slots are modified. I came up with the 
> code below. This is Lispworks so the slot arg is the slot name.
> 
> (defclass signal-class (standard-class)
>  ())
> 
> (defmethod (setf slot-value-using-class) (new-value
>                                               (class signal-class)
>                                               obj
>                                               slot)
>  (format nil "~a-CHANGED" slot)
>  (call-next-method))
> 
> Then when I create a class that uses it it works fine
> 
> (defclass test-class ()
>     ((test-slot))
>     (:metaclass signal-class))
> 
> If I now subclass test-class I get an error that test class is an 
> invalid superclass as the metaclass of test-subclass is standard-class.
> 
> (defclass test-subclass (test-class)
>       ())
> 
> So the question is, have I missed something in my metaclass definition, 
> or if not how do i make a superclass's metaclass persist to its children.

I think what you missed is that classes can have multiple superclasses, 
so it is not a slam dunk that a subclass should have the same metaclass 
as a sole superclass, so it don't by default, so you have to repeat the 
metaclass specification. What I do not recall is if the MOP lets you 
play with the metaclass, but even if it did doing so would mean you had 
forked CLOS, not extended it. No T-shirt for you.

kt


-- 
Well, I've wrestled with reality for 35 years, Doctor, and
I'm happy to state I finally won out over it.
                                   -- Elwood P. Dowd

In this world, you must be oh so smart or oh so pleasant.
                                   -- Elwood's Mom
From: Pascal Costanza
Subject: Re: Metaclass persistence in subclasses
Date: 
Message-ID: <54p6drF210j9tU1@mid.individual.net>
Andrew Lawson wrote:
> Hello all
>     I'm taking my first steps in MOP programming as I need a group of 
> classes that signal when their slots are modified. I came up with the 
> code below. This is Lispworks so the slot arg is the slot name.
> 
> (defclass signal-class (standard-class)
>  ())
> 
> (defmethod (setf slot-value-using-class) (new-value
>                                               (class signal-class)
>                                               obj
>                                               slot)
>  (format nil "~a-CHANGED" slot)
>  (call-next-method))

Just a general note: When the first or last thing in a method is an 
invocation of call-next-method, you can better just define an :after or 
a :before method instead.

> Then when I create a class that uses it it works fine
> 
> (defclass test-class ()
>     ((test-slot))
>     (:metaclass signal-class))
> 
> If I now subclass test-class I get an error that test class is an 
> invalid superclass as the metaclass of test-subclass is standard-class.
> 
> (defclass test-subclass (test-class)
>       ())
> 
> So the question is, have I missed something in my metaclass definition, 
> or if not how do i make a superclass's metaclass persist to its children

By default, the metaclasses of a class and its superclasses must be 
compatible. Also by default, only standard-class and 
funcallable-standard-class are compatible with each other. You can 
declare compatibility of metaclass through methods on 
validate-superclass. However, you have to ensure that the protocols of 
the different metaclasses are indeed compatible. (This can't be decided 
automatically.)

Based on your own responses in this thread, you actually wanted to use 
the same metaclass in the subclass. A common way to ensure that you 
don't forget this is by wrapping this in a macro, say 
define-signal-class (which should be straightforward to implement).

The CLOS MOP doesn't automatically ensure that subclasses inherit the 
metaclasses of their superclasses. With multiple inheritance, that's 
hard to achieve and also questionable, IMHO.


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/