[Rd] surprising behaviour of names<-

Wacek Kusnierczyk Waclaw.Marcin.Kusnierczyk at idi.ntnu.no
Tue Mar 10 23:16:57 CET 2009


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



More information about the R-devel mailing list