[Rd] surprising behaviour of names<-
Wacek Kusnierczyk
Waclaw.Marcin.Kusnierczyk at idi.ntnu.no
Tue Mar 10 18:07:30 CET 2009
Peter Dalgaard wrote:
> Wacek Kusnierczyk wrote:
>
>> playing with 'names<-', i observed the following:
>>
>> x = 1
>> names(x)
>> # NULL
>> 'names<-'(x, 'foo')
>> # c(foo=1)
>> names(x)
>> # NULL
>>
>> where 'names<-' has a functional flavour (does not change x), but:
>>
>> x = 1:2
>> names(x)
>> # NULL
>> 'names<-'(x, 'foo')
>> # c(foo=1, 2)
>> names(x)
>> # "foo" NA
>>
>> where 'names<-' seems to perform a side effect on x (destructively
>> modifies x). furthermore:
>>
>> x = c(foo=1)
>> names(x)
>> # "foo"
>> 'names<-'(x, NULL)
>> names(x)
>> # NULL
>> 'names<-'(x, 'bar')
>> names(x)
>> # "bar" !!!
>>
>> x = c(foo=1)
>> names(x)
>> # "foo"
>> 'names<-'(x, 'bar')
>> names(x)
>> # "bar" !!!
>>
>> where 'names<-' is not only able to destructively remove names from x,
>> but also destructively add or modify them (quite unlike in the first
>> example above).
>>
>> analogous code but using 'dimnames<-' on a matrix performs a side effect
>> on the matrix even if it initially does not have dimnames:
>>
>> x = matrix(1,1,1)
>> dimnames(x)
>> # NULL
>> 'dimnames<-'(x, list('foo', 'bar'))
>> dimnames(x)
>> # list("foo", "bar")
>>
>> this is incoherent with the first example above, in that in both cases
>> the structure initially has no names or dimnames attribute, but the end
>> result is different in the two examples.
>>
>> 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
>
>
that's fine, thanks, but i must be terribly stupid as i do not see how
this explains the examples above. where is the x used by something else
in the first example, so that 'names<-'(x, 'foo') does *not* modify x
destructively, while it does in the other cases?
i just can't see how your explanation fits the examples -- it probably
does, but i beg you show it explicitly.
thanks.
vQ
More information about the R-devel
mailing list