MOP problems -- a fairly basic case - lisp
This is a discussion on MOP problems -- a fairly basic case - lisp ; Maciej Katafiasz wrote:
>>> Actually, as Madhu mentions and I realised shortly after I tried your
>>> suggestion, it's shared-initialize, since it catches redefinitions of
>>> classes as well.
>> You're not allowed to specialize shared-initialize for metaclasses.
>
> ...
-
Re: MOP problems -- a fairly basic case
Maciej Katafiasz wrote:
>>> Actually, as Madhu mentions and I realised shortly after I tried your
>>> suggestion, it's shared-initialize, since it catches redefinitions of
>>> classes as well.
>> You're not allowed to specialize shared-initialize for metaclasses.
>
> Noted. I can't find that passage, though, we're talking about http://
> www.lisp.org/mop/concepts.html#init-class , right?
No, it's at http://www.lisp.org/mop/dictionary.html#%3C/a%3E (last
paragraph).
>>> And just to make sure, the proper way of vetoing class definition in
>>> shared-initialize of its class metaobject is as usual by signalling an
>>> error, right? Is it defined what state the class metaobject will be in,
>>> should the class redefinition fail?
>> You can veto the initialization and reinitialization of metaobject in
>> initialize-instance and reinitialize-instance. If you veto
>> reinitialize-instance, then the metaobject will be in the same state it
>> was before, except for whatever preceding :before and :around methods
>> have already done.
>
> My question was rather "do I have to keep any guarantees about the state
> of the object, or can I clobber it if I signal the error?"
That depends on the semantics of your metaclass. Since it's yours, you
can do whatever you want. 
Just make sure that you document it correctly.
>> If you want to veto the creation of a metaobject, you have to hook on
>> allocate-instance - that's the only way to allocate instances, so
>> everyone has to go through that function.
>
> I see. Given that my classes will have the notion of "well-defined", it
> makes sense to hook into allocate-instance and veto the process as soon
> as possible, right? Though I'll have to hook into reinitialize-instance
> in any case, to handle redefinitions. So either way I get two mehods.
It's a bad idea to have badly initialized objects floating around, for
initial creation it's probably best to hook into allocate-instance if
you cannot otherwise guarantee well-definedness. With reinitialization,
you could indeed ensure that the object remains well-defined.
But maybe it's possible to achieve well-definedness in
initialize-instance even if the user passes bad initialization
arguments. For example, you could define a restart that offers some
default settings...
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/
-
Re: MOP problems -- a fairly basic case
Maciej Katafiasz wrote:
> Den Thu, 15 Nov 2007 14:24:41 +0000 skrev Maciej Katafiasz:
>
>> Noted. I can't find that passage, though, we're talking about http://
>> www.lisp.org/mop/concepts.html#init-class , right?
>
> Nope, it's http://www.lisp.org/mop/dictionary.html#%3C/a%3E
>
> I'm interested in what the rationale behind forbidding SHARED-INITIALIZE
> is.
You're actually not even allowed to define primary methods on
initialize-instance and reinitialize-instance. The reason is that a CLOS
implementation is thus given a lot more freedom on how to actually
construct metaobjects in hopefully more efficient ways than with a naive
approach. Note that if you were allowed to define primary methods here,
or define methods on shared-initialize, it's not clear in what state the
metaobjects actually are, and what side effects have or haven't already
been performed (like informing dependent metaobjects), and so on.
Specifying all these details would be very wordy and cumbersome, and
would put a lot of constraints on CLOS implementations.
A metaobject protocol is a contract between implementors and extenders.
You need a balance somewhere between total freedom for implementors and
total freedom for extenders. You can't have both.
I recommend reading the book "The Art of the Metaobject Protocol" - you
will learn a lot more about such issues...
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/
-
Re: MOP problems -- a fairly basic case
Den Thu, 15 Nov 2007 15:38:23 +0100 skrev Pascal Costanza:
> You're actually not even allowed to define primary methods on
> initialize-instance and reinitialize-instance. The reason is that a CLOS
> implementation is thus given a lot more freedom on how to actually
> construct metaobjects in hopefully more efficient ways than with a naive
> approach. Note that if you were allowed to define primary methods here,
> or define methods on shared-initialize, it's not clear in what state the
> metaobjects actually are, and what side effects have or haven't already
> been performed (like informing dependent metaobjects), and so on.
> Specifying all these details would be very wordy and cumbersome, and
> would put a lot of constraints on CLOS implementations.
>
> A metaobject protocol is a contract between implementors and extenders.
> You need a balance somewhere between total freedom for implementors and
> total freedom for extenders. You can't have both.
>
> I recommend reading the book "The Art of the Metaobject Protocol" - you
> will learn a lot more about such issues...
Yup. I just needed to start working on my MOP-using code before I could
finish reading all the introductory chapters.
Cheers,
Maciej
-
Re: MOP problems -- a fairly basic case
* Pascal Costanza
| Madhu wrote:
|> (defmethod shared-initialize :around ((class serializable) slot-names &rest args &key direct-superclasses)
[...]
| There are some mistakes in here:
Thanks Pascal! For pointing out the bugs, and your suggestions.
| - You are not allowed to define methods on shared-initialize for
| metaclasses. (See "Initialization of Class Metaobjects" in the CLOS
| MOP specification.) So instead, you have to define two methods on
| initialize-instance and reinitialize-instance respectively.
|
| - If :direct-superclasses is not explicitly passed to
| reinitialize-instance, you're not supposed to change anything for that
| parameter. (Same section in the CLOS MOP spec.)
[I haven't been able to spot/infer this one in that section as yet,
still looking...]
| - It's not sufficient that one of the direct superclasses is an
| instance of serializable-class, but it could be that a direct
| superclass inherits from serializable-object in some other way.
The scheme was to automatically add SERIALIZABLE-OBJECT to the
superclasses of any class which is defined to be an instance of
SERIALIZABLE-CLASS. So if any direct superclass was an instance of
SERIALIZABLE-CLASS it would already have SERIALIZABLE-OBJECT as a
superclass. Since SERIALIZABLE-CLASS is the only metaclass the EQ test
(eq (class-of direct-superclass) (find-class 'serializable-class))
would have sufficed in determining whether or not to add
SERIALIZABLE-OBJECT to the superclasses. Is this right or am I missing
something?
--
Madhu
-
Re: MOP problems -- a fairly basic case
Madhu wrote:
> * Pascal Costanza
> | Madhu wrote:
> |> (defmethod shared-initialize :around ((class serializable) slot-names &rest args &key direct-superclasses)
> [...]
> | There are some mistakes in here:
>
> Thanks Pascal! For pointing out the bugs, and your suggestions.
>
> | - You are not allowed to define methods on shared-initialize for
> | metaclasses. (See "Initialization of Class Metaobjects" in the CLOS
> | MOP specification.) So instead, you have to define two methods on
> | initialize-instance and reinitialize-instance respectively.
> |
> | - If :direct-superclasses is not explicitly passed to
> | reinitialize-instance, you're not supposed to change anything for that
> | parameter. (Same section in the CLOS MOP spec.)
>
> [I haven't been able to spot/infer this one in that section as yet,
> still looking...]
Paragraph #7.
> | - It's not sufficient that one of the direct superclasses is an
> | instance of serializable-class, but it could be that a direct
> | superclass inherits from serializable-object in some other way.
>
> The scheme was to automatically add SERIALIZABLE-OBJECT to the
> superclasses of any class which is defined to be an instance of
> SERIALIZABLE-CLASS. So if any direct superclass was an instance of
> SERIALIZABLE-CLASS it would already have SERIALIZABLE-OBJECT as a
> superclass. Since SERIALIZABLE-CLASS is the only metaclass the EQ test
> (eq (class-of direct-superclass) (find-class 'serializable-class))
> would have sufficed in determining whether or not to add
> SERIALIZABLE-OBJECT to the superclasses. Is this right or am I missing
> something?
How do you know that there is no (or will never be a) subclass of
serializable-class?
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/
-
Re: MOP problems -- a fairly basic case
* Pascal Costanza in (5q3dr9Ftnh79U1 @ mid.individual.net )
[...]
|> | - If :direct-superclasses is not explicitly passed to
|> | reinitialize-instance, you're not supposed to change anything for that
|> | parameter. (Same section in the CLOS MOP spec.)
|>
|> [I haven't been able to spot/infer this one in that section as yet,
|> still looking...]
|
| Paragraph #7.
|
|> | - It's not sufficient that one of the direct superclasses is an
|> | instance of serializable-class, but it could be that a direct
|> | superclass inherits from serializable-object in some other way.
|>
|> The scheme was to automatically add SERIALIZABLE-OBJECT to the
|> superclasses of any class which is defined to be an instance of
|> SERIALIZABLE-CLASS. So if any direct superclass was an instance of
|> SERIALIZABLE-CLASS it would already have SERIALIZABLE-OBJECT as a
|> superclass. Since SERIALIZABLE-CLASS is the only metaclass the EQ test
|> (eq (class-of direct-superclass) (find-class 'serializable-class))
|> would have sufficed in determining whether or not to add
|> SERIALIZABLE-OBJECT to the superclasses. Is this right or am I missing
|> something?
|
| How do you know that there is no (or will never be a) subclass of
| serializable-class?
Indeed. As usual, your comments have been valuable,
--
Madhu
Similar Threads
-
By Application Development in forum lisp
Replies: 0
Last Post: 11-15-2007, 04:28 AM
-
By Application Development in forum labview
Replies: 0
Last Post: 08-20-2007, 11:10 AM
-
By Application Development in forum labview
Replies: 1
Last Post: 08-20-2007, 08:40 AM
-
By Application Development in forum labview
Replies: 0
Last Post: 08-20-2007, 07:40 AM
-
By Application Development in forum Graphics
Replies: 1
Last Post: 10-13-2006, 06:53 PM