From simon.urbanek at r-project.org  Wed Mar 11 16:03:32 2009
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Wed, 11 Mar 2009 11:03:32 -0400
Subject: [Rd] surprising behaviour of names<-
In-Reply-To: <96A4BB14-D6EA-44B1-B524-6DB139F3A7F8@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>
Message-ID: <8CCAAAD3-919F-462F-A616-F4FDDB46D975@r-project.org>


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.

Cheers,
Simon


> On Mar 10, 2009, at 18:16 , Wacek Kusnierczyk wrote:
>
>> i got an offline response saying that my original post may have not  
>> been
>> clear as to what the problem was, essentially, and that i may need to
>> restate it in words, in addition to code.
>>
>> the problem is:  the performance of 'names<-' is incoherent, in  
>> that in
>> some situations it acts in a functional manner, producing a copy of  
>> its
>> argument with the names changed, while in others it changes the  
>> object
>> in-place (and returns it), without copying first.  your explanation
>> below is of course valid, but does not seem to address the issue.  in
>> the examples below, there is always (or so it seems) just one  
>> reference
>> to the object.
>>
>> why are the following functional:
>>
>>   x = 1;  'names<-'(x, 'foo'); names(x)
>>   x = 'foo'; 'names<-'(x, 'foo');  names(x)
>>
>> while these are destructive:
>>
>>   x = c(1);  'names<-'(x, 'foo'); names(x)
>>   x = c('foo'); 'names<-'(x, 'foo');  names(x)
>>
>> it is claimed that in r a singular value is a one-element vector, and
>> indeed,
>>
>>   identical(1, c(1))
>>   # TRUE
>>   all.equal(is(1), is(c(1)))
>>   # TRUE
>>
>> i also do not understand the difference here:
>>
>>   x = c(1); 'names<-'(x, 'foo'); names(x)
>>   # "foo"
>>   x = c(1); names(x); 'names<-'(x, 'foo'); names(x)
>>   # "foo"
>>   x = c(1); print(x); 'names<-'(x, 'foo'); names(x)
>>   # NULL
>>   x = c(1); print(c(x)); 'names<-'(x, 'foo'); names(x)
>>   # "foo"
>>
>> does print, but not names, increase the reference count for x when
>> applied to x, but not to c(x)?
>>
>> if the issue is that there is, in those examples where x is left
>> unchanged, an additional reference to x that causes the value of x  
>> to be
>> copied, could you please explain how and when this additional  
>> reference
>> is created?
>>
>>
>> thanks,
>> vQ
>>
>>
>>
>>
>> Peter Dalgaard wrote:
>>>
>>>> is there something i misunderstand here?
>>>>
>>>
>>> Only the ideology/pragmatism... In principle, R has call-by-value
>>> semantics and a function does not destructively modify its  
>>> arguments(*),
>>> and foo(x)<-bar behaves like x <- "foo<-"(x, bar). HOWEVER, this has
>>> obvious performance repercussions (think x <- rnorm(1e7); x[1] <-  
>>> 0), so
>>> we do allow destructive modification by replacement functions,  
>>> PROVIDED
>>> that the x is not used by anything else. On the least suspicion that
>>> something else is using the object, a copy of x is made before the
>>> modification.
>>>
>>> So
>>>
>>> (A) you should not use code like y <- "foo<-"(x, bar)
>>>
>>> because
>>>
>>> (B) you cannot (easily) predict whether or not x will be modified
>>> destructively
>>>
>>> --------
>>> (*) unless you mess with match.call() or substitute() and the  
>>> like. But
>>> that's a different story.
>>>
>>>
>>>
>>
>>
>> -- 
>> -------------------------------------------------------------------------------
>> Wacek Kusnierczyk, MD PhD
>>
>> Email: waku at idi.ntnu.no
>> Phone: +47 73591875, +47 72574609
>>
>> Department of Computer and Information Science (IDI)
>> Faculty of Information Technology, Mathematics and Electrical  
>> Engineering (IME)
>> Norwegian University of Science and Technology (NTNU)
>> Sem Saelands vei 7, 7491 Trondheim, Norway
>> Room itv303
>>
>> Bioinformatics & Gene Regulation Group
>> Department of Cancer Research and Molecular Medicine (IKM)
>> Faculty of Medicine (DMF)
>> Norwegian University of Science and Technology (NTNU)
>> Laboratory Center, Erling Skjalgsons gt. 1, 7030 Trondheim, Norway
>> Room 231.05.060
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>



[Rd] surprising behaviour of names<-
Simon Urbanek