From: J. Kalita
Subject: How do I make an exact copy of an instance in CLOS?
Date: 
Message-ID: <58unan$ppc@harpo.uccs.edu>
Hi!

I was wondering if someone can kindly answer a question
I have about CLOS. I am using the PCL implementation of it.

I want to make an exact copy of an existing instance of a
class. I have not been able to find a way to do this.


For example, I have defined a class called x-structure.

(defclass x-structure ()
  ((specifier :accessor x-specifier :initarg :specifier)
   (head :accessor x-head :initarg :head)
   (complement :accessor x-complement :initarg :complement)
   )
)

Now, I have defined an instance of this structure called *VP-structure*.

(setf *VP-structure*
      (make-instance 'x-structure
         :specifier 'John
	 :head 'loves
	 :complement 'Mary)
     )


Now, I want to make an exact copy of *VP-structure*, say
*VP-structure-2*. I am not sure how to go about it.

Thanks for your time and your answer in advance. 

Jugal Kalita

From: Barry Margolin
Subject: Re: How do I make an exact copy of an instance in CLOS?
Date: 
Message-ID: <591qqg$1o8@tools.bbnplanet.com>
In article <··········@harpo.uccs.edu>,
J. Kalita <······@pikespeak.uccs.edu> wrote:
>I want to make an exact copy of an existing instance of a
>class. I have not been able to find a way to do this.

There's no built-in mechanism for this.  It was decided not to provide a
copying generic function because the right way to copy an instance is often
both type- and context-dependent.  Consider that for lists we have
COPY-LIST, COPY-TREE, and COPY-ALIST -- they all take an object of the same
data type (a list) but perform different, context-dependent copies
(COPY-LIST is shallow, COPY-TREE is deep, and COPY-ALIST is shallow at the
second level).  By the same token, when copying an instance you might want
it to be a deep copy for some slots, shallow for others, and something in
between for others.

>      (make-instance 'x-structure
>         :specifier 'John
>	 :head 'loves
>	 :complement 'Mary)
>     )
>
>
>Now, I want to make an exact copy of *VP-structure*, say
>*VP-structure-2*. I am not sure how to go about it.

(setq *vp-structure-2*
      (make-instance 'x-structure
        :specifier (x-specifier *vp-structure*)
        :head (x-head *vp-structure*)
        :complement (x-complement *vp-structure*)))
-- 
Barry Margolin
BBN Planet, Cambridge, MA
······@bbnplanet.com -  Phone (617) 873-3126 - Fax (617) 873-5508
(BBN customers, please call (800) 632-7638 option 1 for support)
From: Howard R. Stearns
Subject: Re: How do I make an exact copy of an instance in CLOS?
Date: 
Message-ID: <32B57D9C.15FB7483@elwoodcorp.com>
J. Kalita wrote:
> 
> Hi!
> 
> I was wondering if someone can kindly answer a question
> I have about CLOS. I am using the PCL implementation of it.
> 
> I want to make an exact copy of an existing instance of a
> class. I have not been able to find a way to do this.
> 
> For example, I have defined a class called x-structure.
> 
> (defclass x-structure ()
>   ((specifier :accessor x-specifier :initarg :specifier)
>    (head :accessor x-head :initarg :head)
>    (complement :accessor x-complement :initarg :complement)
>    )
> )
> 
> Now, I have defined an instance of this structure called *VP-structure*.
> 
> (setf *VP-structure*
>       (make-instance 'x-structure
>          :specifier 'John
>          :head 'loves
>          :complement 'Mary)
>      )
> 
> Now, I want to make an exact copy of *VP-structure*, say
> *VP-structure-2*. I am not sure how to go about it.
> 
> Thanks for your time and your answer in advance.
> 
> Jugal Kalita

In a separate response to this thread, Barry Margolin gives a good
explanation about why there isn't a single built-in copy-instance
function and what different kinds of copying are possible.

It might be handy to make a shallow-copy generic function, with methods
defined for all your favorite classes.  A default method for
standard-object might use the MetaObject Protocol (MOP) to map over the
slot names  (gathered with: (mapcar #'slot-definition-name (class-slots
(class-of <instance>)))), using them to create an initarg plist for
allocate-instance.

Warning 1: PCL doesn't implement the MOP completely, or uses different
symbols (or different packages) for some utilities.

Warning 2: I'll leave it as an excercise to figure out all the ways in
which this simple mechanism can fail or do the wrong thing, beyond what
Barry points out.  Consider slots intended for caching, slots using
other than :instance :allocation, and the intent of
:before/:after/:around methods on accessor methods.

Advice: Pick up a copy of:
  The Art of the Metaobject Protocol, by Kiczales, des Rivieres, and
Bobrow, MIT Press, 1991.  ISBN 0-262-11158-6 (hc) 0-262-61074-4 (pbk)