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

Tony Plate
Sat, 11 Jun 2005 13:18:53 -0000

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
>>
>
>