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/