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?
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
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/
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.
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.
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/
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/
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.
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