From: Jim Newton
Subject: closette calls shared-initialize rather than reinitialize-instance
Date:
Message-ID: <44c65ddc$1@news.cadence.com>
I have a version of closette.lisp
;;; Closette Version 1.0 (February 10, 1991)
which i downloaded at some point in the past.
I think the definition of update-instance-for-different-class
should be calling reinitialize-instance rather than
shared-initialize.
Does anyone agree? This version of closette defines
reinitialize-instance but never seems to call it.
(defmethod update-instance-for-different-class
((old standard-object) (new standard-object) &rest initargs)
(let ((added-slots
(remove-if #'(lambda (slot-name)
(slot-exists-p old slot-name))
(mapcar #'slot-definition-name
(class-slots (class-of new))))))
(apply #'shared-initialize new added-slots initargs)))
--
+------------------------------------------------------------------------+
| Jim E. Newton (·····@cadence.com) desk +49-(0)89-4563-1918 |
| Methodology Services Europe fax +49-(0)89-4563-1819 |
| Cadence Design Systems GmbH Munich Germany |
| |
| If you won't do it in the rain, you won't do it. |
+------------------------------------------------------------------------+
From: Jim Newton
Subject: Re: closette calls shared-initialize rather than reinitialize-instance
Date:
Message-ID: <44c664ce$1@news.cadence.com>
Hmm, i think i spoke too soon. :-( I was thinking that
reinitialize-instance should be used to do initialization you
only want on change-class, but that does not seem to be the
case once i read a bit of the hyperspec.
Where is the best place to put code that i want exectuted on
change-class, but not on make-instance?
I suppose I should put a before/after method on change-class
or perhaps on update-instance-for-differnt-class? it seems a bit
obvious now.
-jim
Jim Newton wrote:
> I have a version of closette.lisp
> ;;; Closette Version 1.0 (February 10, 1991)
> which i downloaded at some point in the past.
>
> I think the definition of update-instance-for-different-class
> should be calling reinitialize-instance rather than
> shared-initialize.
>
> Does anyone agree? This version of closette defines
> reinitialize-instance but never seems to call it.
>
> (defmethod update-instance-for-different-class
> ((old standard-object) (new standard-object) &rest initargs)
> (let ((added-slots
> (remove-if #'(lambda (slot-name)
> (slot-exists-p old slot-name))
> (mapcar #'slot-definition-name
> (class-slots (class-of new))))))
> (apply #'shared-initialize new added-slots initargs)))
>
>
>
--
+------------------------------------------------------------------------+
| Jim E. Newton (·····@cadence.com) desk +49-(0)89-4563-1918 |
| Methodology Services Europe fax +49-(0)89-4563-1819 |
| Cadence Design Systems GmbH Munich Germany |
| |
| If you won't do it in the rain, you won't do it. |
+------------------------------------------------------------------------+
From: Pascal Costanza
Subject: Re: closette calls shared-initialize rather than reinitialize-instance
Date:
Message-ID: <4inl99F4ioh3U1@individual.net>
Jim Newton wrote:
> Hmm, i think i spoke too soon. :-( I was thinking that
> reinitialize-instance should be used to do initialization you
> only want on change-class, but that does not seem to be the
> case once i read a bit of the hyperspec.
In "pure" ANSI Common Lisp (without the CLOS MOP), reinitialize-instance
only exists for the user so that slots can be reinitialized. None of the
protocols defined in the HyperSpec call reinitialize-instance.
There are some places in the CLOS MOP specification where
reinitialize-instance is explicitly specified to be called by some
protocols. But not by change-class.
> Where is the best place to put code that i want exectuted on
> change-class, but not on make-instance?
Er, change-class. ;) Seriously, change-class is a generic function and
you can define methods on it...
> I suppose I should put a before/after method on change-class
> or perhaps on update-instance-for-differnt-class? it seems a bit
> obvious now.
Yep.
Make sure that at least one of the specializers in your methods for
change-class or update-instance-for-different-class is your own class.
(See item 19 in 11.1.2.1.2 of the HyperSpec.)
Pascal
--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Jim Newton
Subject: Re: closette calls shared-initialize rather than reinitialize-instance
Date:
Message-ID: <44c70cd1$1@news.cadence.com>
Thanks for the clarification, can you give an example of
why i would want to call reinitialize-instance?
Perhaps for performance reason, if i know i'm finished
with an instance but want to allocate a new one, i might
just recycle an old one? Is there another example?
-jim
Pascal Costanza wrote:
> Jim Newton wrote:
>
>> Hmm, i think i spoke too soon. :-( I was thinking that
>> reinitialize-instance should be used to do initialization you
>> only want on change-class, but that does not seem to be the
>> case once i read a bit of the hyperspec.
>
>
> In "pure" ANSI Common Lisp (without the CLOS MOP), reinitialize-instance
> only exists for the user so that slots can be reinitialized. None of the
> protocols defined in the HyperSpec call reinitialize-instance.
>
> There are some places in the CLOS MOP specification where
> reinitialize-instance is explicitly specified to be called by some
> protocols. But not by change-class.
>
>> Where is the best place to put code that i want exectuted on
>> change-class, but not on make-instance?
>
>
> Er, change-class. ;) Seriously, change-class is a generic function and
> you can define methods on it...
>
>> I suppose I should put a before/after method on change-class
>> or perhaps on update-instance-for-differnt-class? it seems a bit
>> obvious now.
>
>
> Yep.
>
> Make sure that at least one of the specializers in your methods for
> change-class or update-instance-for-different-class is your own class.
> (See item 19 in 11.1.2.1.2 of the HyperSpec.)
>
> Pascal
>
--
+------------------------------------------------------------------------+
| Jim E. Newton (·····@cadence.com) desk +49-(0)89-4563-1918 |
| Methodology Services Europe fax +49-(0)89-4563-1819 |
| Cadence Design Systems GmbH Munich Germany |
| |
| If you won't do it in the rain, you won't do it. |
+------------------------------------------------------------------------+
From: Pascal Costanza
Subject: Re: closette calls shared-initialize rather than reinitialize-instance
Date:
Message-ID: <4iop6cF4msj4U1@individual.net>
Jim Newton wrote:
> Thanks for the clarification, can you give an example of
> why i would want to call reinitialize-instance?
> Perhaps for performance reason, if i know i'm finished
> with an instance but want to allocate a new one, i might
> just recycle an old one? Is there another example?
Recycling old objects is probably not a good use case - modern garbage
collectors are typically better at that.
In the CLOS MOP, reinitialize-instance is used to bundle the effects of
changing several slots at once. Consider that when you change the
definition of a class (for example, via issuing a defclass form for a
class that already exists) that a lot of consequences have to be
determined, like changes to existing objects, changes to subclasses,
invalidation of caches for generic functions that are specialized on the
respective classes, and so on. If you would do this after each slot
change, this would lead to unnecessary overhead. So instead of...
(setf (slot-value class 'direct-superclasses) ...)
(setf (slot-value class 'direct-slots) ...)
(setf (slot-value class 'documentation) ...)
...
...CLOS can just call this:
(reinitialize-instance class
:direct-superclasses ...
:direct-slots ...
:documentation ...
...)
This means that the effects of changes to slots can be computed once for
a whole bunch of changed slots, for example in an :after method on
reinitialize-instance. In principle, it would also be possible to do this:
(setf (slot-value class 'direct-superclasses) ...)
(setf (slot-value class 'direct-slots) ...)
(setf (slot-value class 'documentation) ...)
...
(reinitialize-instance class)
So slots could be changed one by one, and then finally the effects of
changing the slots could be triggered. However, the CLOS MOP doesn't
grant direct access to specified properties of metaobject classes.
Nevertheless, this could be an idea for your own designs.
I guess that's the main use case for reinitialize-instance - at least at
the moment I can't think of another one.
Pascal
--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: Pascal Costanza
Subject: Re: closette calls shared-initialize rather than reinitialize-instance
Date:
Message-ID: <4inleeF4ioh3U2@individual.net>
Jim Newton wrote:
> I have a version of closette.lisp
> ;;; Closette Version 1.0 (February 10, 1991)
> which i downloaded at some point in the past.
>
> I think the definition of update-instance-for-different-class
> should be calling reinitialize-instance rather than
> shared-initialize.
>
> Does anyone agree? This version of closette defines
> reinitialize-instance but never seems to call it.
>
> (defmethod update-instance-for-different-class
> ((old standard-object) (new standard-object) &rest initargs)
> (let ((added-slots
> (remove-if #'(lambda (slot-name)
> (slot-exists-p old slot-name))
> (mapcar #'slot-definition-name
> (class-slots (class-of new))))))
> (apply #'shared-initialize new added-slots initargs)))
It's important to note that Closette is only a pedagogical device to
teach the basic concepts of a metaobject protocol. None of the details
in Closette allow drawing conclusions for CLOS and its MOP, which have
specifications that in some places deviate strongly from Closette.
Pascal
--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/