From ripley at stats.ox.ac.uk  Wed Jun 28 11:12:08 2006
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Wed, 28 Jun 2006 10:12:08 +0100 (BST)
Subject: [Rd] [R] assign / environment side effect on R 2.4.0
In-Reply-To: <x28xnkt9g8.fsf@viggo.kubism.ku.dk>
References: <449BFB16.6010501@TU-Dresden.de>
	<449C0A4E.9040203@hhbio.wasser.tu-dresden.de>
	<Pine.LNX.4.64.0606261120370.23616@gannet.stats.ox.ac.uk>
	<971536df0606260424x27e7143ap22ecaaedd11dbd8c@mail.gmail.com>
	<x28xnkt9g8.fsf@viggo.kubism.ku.dk>
Message-ID: <Pine.LNX.4.64.0606280937190.10252@gannet.stats.ox.ac.uk>

That is quite a different point, and nothing to do with 'R 2.4.0' or any 
recent version of R.  The example

envfun <- function(L) {
   p <- parent.frame()
   assign("test", L$test, p)
   environment(p$test) <- p
}
solver <- function(L) envfun(L)
L <- list(test = function() 1 + 2)

environment(L$test)
solver(L)
(e <- environment(L$test))
stopifnot(identical(e, .GlobalEnv))

fails in 2.2.1 (as Thomas had already said) and indeed in much earlier 
versions of R (e.g. 2.0.0).

As a glance at the code would have shown, environment<- was written 
without any regard for NAMED bits, and so changes the environment on all 
copies of the function.  This may well have been intentional (and seems to 
have been the same in the orginal CVS version in 1997), but I have altered 
it for 2.4.0.


On Mon, 26 Jun 2006, Peter Dalgaard wrote:

> "Gabor Grothendieck" <ggrothendieck at gmail.com> writes:
>
>> I have moved this discussion to r-devel.
>>
>> The example of the poster suggests that the functionality as implemented
>> so far in the upcoming 2.4.0 is at this point not correct and needs to
>> be fixed prior to release.

[Given that we had already been told the side effect existed in 2.2.1, 
this was a careless analysis.]

>> It violates the idea in R that if one modifies a list in a function then a copy
>> of that list gets created (at least conceptually) for use within a function
>> (rather than the original list being modified) and effectively turns what would
>> have been a local variable into an error-prone global variable.
>>
>>
>> On 6/26/06, Prof Brian Ripley <ripley at stats.ox.ac.uk> wrote:
>>> Please do study the posting guide, as there is no `R 2.4.0'.
>>>
>>> This seems to be related to the NEWS item
>>>
>>>     o  [[ on a list does not duplicate the extracted element unless
>>>        necessary.  (It did not duplicate in other cases, e.g. a
>>>        pairlist.)
>>>
>>> Now in so far as I can follow it, in your example [[ behaves in the same
>>> way as $ always did (which is what informed people would expect).
>
> Well, informed people would expect $ and [[ to behave the same, but
> they would _not_ expect
>
>> e1 <- environment(L$test)
>> solver(L)
>> e2 <- environment(L$test)
>> print(e1)
> <environment: R_GlobalEnv>
>> print(e2)
> <environment: 0x12f23a8>
>
> unless perhaps substitute() or similar magic was invoked inside
> solver() to create call-by-reference semantics. What we have is an
> assignment to "test" in the evaluation frame of solver(), which is a
> shallow copy of a shallow copy of L$test, so NAMED should be 2 and
> modification should force duplication.
>
> In R-devel, this happens with both [[ and $, and in earlier versions
> apparently only with $, which seems to be a case where fixing one bug
> unmasks another - i.e. $ was always wrong, now both are.
>
> As far as I can see, either assign() or environment<-() has the bug.
>
>>> R-help is not the place to discuss unreleased versions of R, nor for
>>> questions about code development.  (Did I mention studying the posting
>>> guide?)
>>>
>>>
>>> On Fri, 23 Jun 2006, Thomas Petzoldt wrote:
>>>
>>>> Sorry,
>>>>
>>>> the posted example had the side effect on all platforms (correctly: R
>>>> 2.2.1/Windows, 2.3.1/Linux, 2.4.0/Windows), but in the following
>>>> corrected example the behavior of 2.4.0 differs from the older versions.
>>>>
>>>> The only difference between the "wrong" and the "new" example is
>>>> L[["test"]] vs. L$test in the assign.
>>>>
>>>> Thomas P.
>>>>
>>>>
>>>> envfun <- function(L) {
>>>> #  L <- as.list(unlist(L))
>>>>  p <- parent.frame()
>>>>  assign("test", L[["test"]], p) ## [["test"]] instead of $test
>>>>  environment(p[["test"]]) <- p
>>>> }
>>>>
>>>>
>>>> solver <- function(L) {
>>>>  envfun(L)
>>>>  # some other stuff
>>>> }
>>>>
>>>> L <- list(test = function() 1 + 2)
>>>>
>>>> e1 <- environment(L$test)
>>>> solver(L)
>>>> e2 <- environment(L$test)
>>>>
>>>> print(e1)
>>>> print(e2)
>>>>
>>>> ______________________________________________
>>>> R-help at stat.math.ethz.ch mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>>> PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>>>>
>>>
>>> --
>>> Brian D. Ripley,                  ripley at stats.ox.ac.uk
>>> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
>>> University of Oxford,             Tel:  +44 1865 272861 (self)
>>> 1 South Parks Road,                     +44 1865 272866 (PA)
>>> Oxford OX1 3TG, UK                Fax:  +44 1865 272595
>>>
>>> ______________________________________________
>>> R-help at stat.math.ethz.ch mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>> PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>>>
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
>

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595



[Rd] [R] assign / environment side effect on R 2.4.0
Prof Brian Ripley