From: Eduardo Martín Rojo
Subject: Copy-struct dude
Date: 
Message-ID: <c327d0$8dq$1@news.ya.com>
Hello,

   I am a newbie in Lisp, and I have a problem that probably would sound 
a little silly to you, but is because I'm just starting to learn this 
programming language.

My dude is the following:

I want to develope a function that takes as argument a struct, and 
returns the same struct but with little changes in his content. The 
function is something like this:


(defstruct my-struct
   (x)
   (y)
)

(defun my-function (state)
   (let* ((state2 (copy-my-struct state)))
     (setf (my-struct-x state2) 'a)
     state2
    )
)

But the problem is that when I do this:

(my-function *my-own-state*)

the contents of global variable *my-own-state* are modified by de 
function "my-function". I think that the function "copy-..." don't 
create a new struct; it just makes state2 reference the contents of 
*my-own-state*. Is this true?

From: Kenny Tilton
Subject: Re: Copy-struct dude
Date: 
Message-ID: <Ll25c.22798$tP6.5893184@twister.nyc.rr.com>
Eduardo Mart�n Rojo wrote:

> Hello,
> 
>   I am a newbie in Lisp, and I have a problem that probably would sound 
> a little silly to you, but is because I'm just starting to learn this 
> programming language.
> 
> My dude is the following:
> 
> I want to develope a function that takes as argument a struct, and 
> returns the same struct but with little changes in his content. The 
> function is something like this:
> 
> 
> (defstruct my-struct
>   (x)
>   (y)
> )
> 
> (defun my-function (state)
>   (let* ((state2 (copy-my-struct state)))
>     (setf (my-struct-x state2) 'a)
>     state2
>    )
> )
> 
> But the problem is that when I do this:
> 
> (my-function *my-own-state*)
> 
> the contents of global variable *my-own-state* are modified by de 
> function "my-function".

They should not be. You did not show the actual code exhibiting this 
behavior. Maybe the problem is there. Show us that. This worked for me:

(defstruct my-struct
   (x)
   (y))

(defun my-function (state)
   (let* ((state2 (copy-my-struct state)))
     (setf (my-struct-x state2) 'a)
     state2))

(DEFvar *my-own-state*)

(let ((*my-own-state* (make-my-struct :x 'ny)))
   (let ((a (my-function *my-own-state*)))
     (list (my-struct-x a) (my-struct-x *my-own-state*))))

=> (A NY)

-- 
http://tilton-technology.com

Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film

Your Project Here! http://alu.cliki.net/Industry%20Application
From: Pascal Bourguignon
Subject: Re: Copy-struct dude
Date: 
Message-ID: <878yi3meji.fsf@thalassa.informatimago.com>
Eduardo Mart�n Rojo <······················@ya.com> writes:
> the contents of global variable *my-own-state* are modified by de
> function "my-function". I think that the function "copy-..." don't
> create a new struct; it just makes state2 reference the contents of
> *my-own-state*. Is this true?

I don't see this behavior:


[2]> (defstruct my-struct
   (x)
   (y)
)
(defun my-function (state)
   (let* ((state2 (copy-my-struct state)))
     (setf (my-struct-x state2) 'a)
     state2
    )
)
MY-STRUCT
[9]> 
MY-FUNCTION
[10]> (defparameter  *my-own-state* (make-my-struct :x 1 :y 2))
*MY-OWN-STATE*
[11]> (my-function *my-own-state* )
#S(MY-STRUCT :X A :Y 2)
[12]> *my-own-state*
#S(MY-STRUCT :X 1 :Y 2)


Of course, you should assume that you get equal y fields:

[13]> (defparameter  *my-own-state* (make-my-struct :x 1 :y '(a b)))
*MY-OWN-STATE*
[14]> (eq (my-struct-y (my-function *my-own-state*)) (my-struct-y *my-own-state*))
T


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Kalle Olavi Niemitalo
Subject: Re: Copy-struct dude
Date: 
Message-ID: <87n06jm9m6.fsf@Astalo.kon.iki.fi>
Eduardo Mart�n Rojo <······················@ya.com> writes:

> But the problem is that when I do this:
> 
> (my-function *my-own-state*)
> 
> the contents of global variable *my-own-state* are modified by de
> function "my-function".

Doesn't happen on CMUCL:

* (defparameter *my-own-state* (make-my-struct :x 1 :y 2))
*MY-OWN-STATE*
* (my-function *my-own-state*)
#S(MY-STRUCT :X A :Y 2)
* *my-own-state*
#S(MY-STRUCT :X 1 :Y 2)

> I think that the function "copy-..." don't create a new struct;
> it just makes state2 reference the contents of *my-own-state*.
> Is this true?

No, it isn't.  The whole point of the function is to make a copy.

On the other hand, if you have e.g. a list in a slot of the
structure object, then the copy will refer to the same list.
That is, only the structure itself is copied, not the objects to
which the slots refer.  If you want a deep copy, you'll have to
implement that yourself.
From: =?ISO-8859-15?Q?Eduardo_Mart=EDn_Rojo?=
Subject: Re: Copy-struct dude
Date: 
Message-ID: <c32pae$1l7$1@news.ya.com>
Yes, you were right. I was storing lists in the slots of de struct and 
in the copy, the new struct copy the reference to the list, and don't 
create a new list for storing that data.

Lot of thanks

Kalle Olavi Niemitalo escribi�:
> Eduardo Mart�n Rojo <······················@ya.com> writes:
> 
> 
>>But the problem is that when I do this:
>>
>>(my-function *my-own-state*)
>>
>>the contents of global variable *my-own-state* are modified by de
>>function "my-function".
> 
> 
> Doesn't happen on CMUCL:
> 
> * (defparameter *my-own-state* (make-my-struct :x 1 :y 2))
> *MY-OWN-STATE*
> * (my-function *my-own-state*)
> #S(MY-STRUCT :X A :Y 2)
> * *my-own-state*
> #S(MY-STRUCT :X 1 :Y 2)
> 
> 
>>I think that the function "copy-..." don't create a new struct;
>>it just makes state2 reference the contents of *my-own-state*.
>>Is this true?
> 
> 
> No, it isn't.  The whole point of the function is to make a copy.
> 
> On the other hand, if you have e.g. a list in a slot of the
> structure object, then the copy will refer to the same list.
> That is, only the structure itself is copied, not the objects to
> which the slots refer.  If you want a deep copy, you'll have to
> implement that yourself.
From: John Thingstad
Subject: Re: Copy-struct dude
Date: 
Message-ID: <opr4woe8qxxfnb1n@news.chello.no>
On Mon, 15 Mar 2004 00:19:34 +0100, Eduardo Mart�n Rojo 
<······················@ya.com> wrote:

using copy-list on the lists in the slots should solve it.

> Yes, you were right. I was storing lists in the slots of de struct and 
> in the copy, the new struct copy the reference to the list, and don't 
> create a new list for storing that data.
>
> Lot of thanks
>
> Kalle Olavi Niemitalo escribi�:
>> Eduardo Mart�n Rojo <······················@ya.com> writes:
>>
>>
>>> But the problem is that when I do this:
>>>
>>> (my-function *my-own-state*)
>>>
>>> the contents of global variable *my-own-state* are modified by de
>>> function "my-function".
>>
>>
>> Doesn't happen on CMUCL:
>>
>> * (defparameter *my-own-state* (make-my-struct :x 1 :y 2))
>> *MY-OWN-STATE*
>> * (my-function *my-own-state*)
>> #S(MY-STRUCT :X A :Y 2)
>> * *my-own-state*
>> #S(MY-STRUCT :X 1 :Y 2)
>>
>>
>>> I think that the function "copy-..." don't create a new struct;
>>> it just makes state2 reference the contents of *my-own-state*.
>>> Is this true?
>>
>>
>> No, it isn't.  The whole point of the function is to make a copy.
>>
>> On the other hand, if you have e.g. a list in a slot of the
>> structure object, then the copy will refer to the same list.
>> That is, only the structure itself is copied, not the objects to
>> which the slots refer.  If you want a deep copy, you'll have to
>> implement that yourself.



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
From: Raymond Wiker
Subject: Re: Copy-struct dude
Date: 
Message-ID: <86znaidxdy.fsf@raw.grenland.fast.no>
John Thingstad <··············@chello.no> writes:

> On Mon, 15 Mar 2004 00:19:34 +0100, Eduardo Mart�n Rojo
> <······················@ya.com> wrote:
>
> using copy-list on the lists in the slots should solve it.

        copy-tree may be more appropriate... in any case, it is
probably necessary to write a copy-* function for the structure to
ensure that everything is copied. defstruct has a :copier option that
should be used to override the default generated by defstruct. For
CLOS classes, there is probably a generic function that should be
specialized.


-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Tim Bradshaw
Subject: Re: Copy-struct dude
Date: 
Message-ID: <fbc0f5d1.0403151213.3282d836@posting.google.com>
Raymond Wiker <·············@fast.no> wrote in message news:<··············@raw.grenland.fast.no>...

> 
>         copy-tree may be more appropriate... in any case, it is
> probably necessary to write a copy-* function for the structure to
> ensure that everything is copied. defstruct has a :copier option that
> should be used to override the default generated by defstruct. For
> CLOS classes, there is probably a generic function that should be
> specialized.

There isn't and nor should there be.  See cll passim for why.
From: Marco Antoniotti
Subject: Re: Copy-struct dude
Date: 
Message-ID: <CFY5c.103$IJ5.80720@typhoon.nyu.edu>
Tim Bradshaw wrote:
> Raymond Wiker <·············@fast.no> wrote in message news:<··············@raw.grenland.fast.no>...
> 
> 
>>        copy-tree may be more appropriate... in any case, it is
>>probably necessary to write a copy-* function for the structure to
>>ensure that everything is copied. defstruct has a :copier option that
>>should be used to override the default generated by defstruct. For
>>CLOS classes, there is probably a generic function that should be
>>specialized.
> 
> 
> There isn't and nor should there be.  See cll passim for why.

I disagree.  There should be a generic COPY function for most CL data 
types (i.e. there should be a COPY method for ARRAYS) and "hic sunt 
leones" posts around it.  The lack of such common hook is a nuisance.

How many people out there have done the following?

(defpackage "MY-COPIER" (:use "CL") (:export "COPY")

(in-package "MY-COPIER")

(defgeneric copy (x))



The same can be said of EQUAL and SXHASH.

Java does the right thing in this respect.  The only reasons I can come 
up for the current state of affairs are historical.

Cheers
--
Marco