From Waclaw.Marcin.Kusnierczyk at idi.ntnu.no  Thu Mar 12 21:54:34 2009
From: Waclaw.Marcin.Kusnierczyk at idi.ntnu.no (Wacek Kusnierczyk)
Date: Thu, 12 Mar 2009 21:54:34 +0100
Subject: [Rd] surprising behaviour of names<-
In-Reply-To: <1C7E6CAE-222C-4A7D-B9E6-CC27692D65BB@r-project.org>
References: <49B67CB1.8060005@idi.ntnu.no>
	<49B682F9.8050307@biostat.ku.dk>	<49B6E6D9.7010809@idi.ntnu.no>	<96A4BB14-D6EA-44B1-B524-6DB139F3A7F8@r-project.org>
	<8CCAAAD3-919F-462F-A616-F4FDDB46D975@r-project.org>
	<49B92643.6060401@idi.ntnu.no>
	<1C7E6CAE-222C-4A7D-B9E6-CC27692D65BB@r-project.org>
Message-ID: <49B9768A.9070103@idi.ntnu.no>

Simon Urbanek wrote:
>
> On Mar 12, 2009, at 11:12 , Wacek Kusnierczyk wrote:
>
>> Simon Urbanek wrote:
>>>
>>> On Mar 11, 2009, at 10:52 , Simon Urbanek wrote:
>>>
>>>> Wacek,
>>>>
>>>> Peter gave you a full answer explaining it very well. If you really
>>>> want to be able to trace each instance yourself, you have to learn
>>>> far more about R internals than you apparently know (and Peter hinted
>>>> at that). Internally x=1 an x=c(1) are slightly different in that the
>>>> former has NAMED(x) = 2 whereas the latter has NAMED(x) = 0 which is
>>>> what causes the difference in behavior as Peter explained. The reason
>>>> is that c(1) creates a copy of the 1 (which is a constant
>>>> [=unmutable] thus requiring a copy) and the new copy has no other
>>>> references and thus can be modified and hence NAMED(x) = 0.
>>>>
>>>
>>> Errata: to be precise replace NAMED(x) = 0 with NAMED(x) = 1 above --
>>> since NAMED(c(1)) = 0 and once it's assigned to x it becomes NAMED(x)
>>> = 1 -- this is just a detail on how things work with assignment, the
>>> explanation above is still correct since duplication happens
>>> conditional on NAMED == 2.
>>
>> there is an interesting corollary.  self-assignment seems to increase
>> the reference count:
>>
>>    x = 1;  'names<-'(x, 'foo'); names(x)
>>    # NULL
>>
>>    x = 1;  x = x;  'names<-'(x, 'foo'); names(x)
>>    # "foo"
>>
>
> Not for me, at least in current R:

not for me either.  i messed up the example, sorry.  here's the intended
version:

    x = c(1);  'names<-'(x, 'foo');  names(x)
    # "foo"

    x = c(1);  x = x; 'names<-'(x, 'foo');  names(x)
    # NULL
  

>
> > x = 1;  'names<-'(x, 'foo'); names(x)
> foo
>   1
> NULL
> > x = 1;  x = x;  'names<-'(x, 'foo'); names(x)
> foo
>   1
> NULL
>
> (both R 2.8.1 and R-devel 3/11/09, darwin 9.6)
>
> In addition, you still got it backwards - your output suggests that
> the assignment created a new, clean copy. Functional call of `names<-`
> (whose side-effect on x is undefined BTW) is destructive when you get
> a clean copy (e.g. as a result of the c function) and non-destructive
> when the object was referenced. It is left as an exercise to the
> reader to reason why constants such as 1 are referenced.

all true, again because of my mistake. 

anyway, it may be suprising that with all its smartness (i mean it)
about copy-on-assingment, r does not see that it makes no sense to
increase refcount here.  of course, you can't judge from just the
syntactic form 'x=x', but still it should not be very difficult to have
the interpreter see when it finds an object named 'x' in the same
environment where it attempts the assignment.  (of course, who'd do
self-assignments in practical code?)

cheers,
vQ



[Rd] surprising behaviour of names<-
Wacek Kusnierczyk