From tplate at blackmesacapital.com  Sat Jun 11 15:18:53 2005
From: tplate at blackmesacapital.com (Tony Plate)
Date: Sat, 11 Jun 2005 07:18:53 -0600
Subject: [Rd] single assignment affecting multiple sub-structures
	(PR#7924)
In-Reply-To: <40e66e0b05060911107dda7eae@mail.gmail.com>
References: <20050609171307.C73FFA1EB@slim.kubism.ku.dk>
	<40e66e0b05060911107dda7eae@mail.gmail.com>
Message-ID: <42AAE4BD.7090307@blackmesacapital.com>

Yes, actually, I have had code using do.call() that returns the result I 
want working for years.  However, I've been trying to reduce the memory 
usage of my code, and I discovered that in S-PLUS, do.call() appears to 
make a extra copy of its arguments.  When the arguments are very large, 
this can be important.  I found that by constructing a call like the one 
below, and eval()ing it, S-PLUS would not make unnecessary copies of the 
arguments.

However, when I tried the same code in R, I found the bug that I 
described below.

-- Tony Plate

Douglas Bates wrote:
> I hesitate to make such as simplistic suggestion but have you
> considered using do.call to generate the call?
> 
> On 6/9/05, tplate at blackmesacapital.com <tplate at blackmesacapital.com> wrote:
> 
>>I'm trying to create a language structure that is a call to a function
>>with a number of arguments that is only known at run time.  I do this by
>>using repeated indices to expand out a call with a single argument.
>>However, when I change one of the arguments, all are changed.
>>
>>I don't see the same behavior when I initially create a call with
>>multiple arguments.
>>
>>Even more strangely, calling identical(call1, call2) before any attempts
>>to modify the structures changes the subsequent behavior to be correct.
>>
>>[If there are better methods to create and modify calls, please let me
>>know!]
>>
>> > # Example of commands that give incorrect results
>> > call1 <- Quote(f(arg[[1]], arg[[1]], arg[[1]]))
>> > call2 <- Quote(f(arg[[1]]))[c(1,2,2,2)]
>> > call1
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call2
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call1[[3]][[3]] <- 2
>> > call2[[3]][[3]] <- 2
>> > call1
>>f(arg[[1]], arg[[2]], arg[[1]])
>> > # note that all the arguments of call2 have changed!
>> > call2
>>f(arg[[2]], arg[[2]], arg[[2]])
>> > identical(call1, call2)
>>[1] FALSE
>> >
>> > # if we do 'identical(call1, call2)' directly
>> > # after creation, then everything behaves correctly !??
>> > call1 <- Quote(f(arg[[1]], arg[[1]], arg[[1]]))
>> > call2 <- Quote(f(arg[[1]]))[c(1,2,2,2)]
>> > identical(call1, call2)
>>[1] TRUE
>> > call1
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call2
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call1[[3]][[3]] <- 2
>> > call2[[3]][[3]] <- 2
>> > call1
>>f(arg[[1]], arg[[2]], arg[[1]])
>> > call2
>>f(arg[[1]], arg[[2]], arg[[1]])
>> > identical(call1, call2)
>>[1] TRUE
>> >
>> > # The same thing happens when the call is created using 'call()'
>> > call3 <- call("f", call("[[", as.name("arg"), 1))[c(1,2,2,2)]
>> > call3
>>f(arg[[1]], arg[[1]], arg[[1]])
>> > call3[[3]][[3]] <- 2
>> > call3
>>f(arg[[2]], arg[[2]], arg[[2]])
>> >
>> > version
>>          _
>>platform i386-pc-mingw32
>>arch     i386
>>os       mingw32
>>system   i386, mingw32
>>status
>>major    2
>>minor    1.0
>>year     2005
>>month    04
>>day      18
>>language R
>> >
>>
>>
>>I also see the same behavior in the development release of R:
>> > version
>>          _
>>platform i386-pc-mingw32
>>arch     i386
>>os       mingw32
>>system   i386, mingw32
>>status   Under development (unstable)
>>major    2
>>minor    2.0
>>year     2005
>>month    06
>>day      07
>>svn rev  34588
>>language R
>> >
>>
>>-- Tony Plate
>>
>>______________________________________________
>>R-devel at stat.math.ethz.ch mailing list
>>https://stat.ethz.ch/mailman/listinfo/r-devel
>>
> 
>



[Rd] single assignment affecting multiple sub-structures (PR#7924)
Tony Plate