On Nov 24, 2011, at 11:13 , Matthew Dowle wrote:
Hi,
I expected NAMED to be 1 in all these three cases. It is for one of
them,
but not the other two?
R --vanilla
R version 2.14.0 (2011-10-31)
Platform: i386-pc-mingw32/i386 (32-bit)
x = 1L
.Internal(inspect(x)) # why NAM(2)? expected NAM(1)
@2514aa0 13 INTSXP g0c1 [NAM(2)] (len=1, tl=0) 1
y = 1:10
.Internal(inspect(y)) # NAM(1) as expected but why different to x?
@272f788 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 1,2,3,4,5,...
z = data.frame()
.Internal(inspect(z)) # why NAM(2)? expected NAM(1)
@24fc28c 19 VECSXP g0c0 [OBJ,NAM(2),ATT] (len=0, tl=0)
ATTRIB:
@24fc270 02 LISTSXP g0c0 []
TAG: @3f2120 01 SYMSXP g0c0 [MARK,gp=0x4000] "names"
@24fc334 16 STRSXP g0c0 [] (len=0, tl=0)
TAG: @3f2040 01 SYMSXP g0c0 [MARK,gp=0x4000] "row.names"
@24fc318 13 INTSXP g0c0 [] (len=0, tl=0)
TAG: @3f2388 01 SYMSXP g0c0 [MARK,gp=0x4000] "class"
@25be500 16 STRSXP g0c1 [] (len=1, tl=0)
@1d38af0 09 CHARSXP g0c2 [MARK,gp=0x21,ATT] "data.frame"
It's a little difficult to search for the word "named" but I tried and
found this in R-ints :
"Note that optimizing NAMED = 1 is only effective within a primitive
(as the closure wrapper of a .Internal will set NAMED = 2 when the
promise to the argument is evaluated)"
So might it be that just looking at NAMED using .Internal(inspect()) is
setting NAMED=2? But if so, why does y have NAMED==1?
This is tricky business... I'm not quite sure I'll get it right, but let's
try
When you are assigning a constant, the value you assign is already part of
the assignment expression, so if you want to modify it, you must
duplicate. So NAMED==2 on z<- 1 is basically to prevent you from
accidentally "changing the value of 1". If it weren't, then you could get
bitten by code like for(i in 1:2) {z<- 1; if(i==1) z[1]<- 2}.
If you're assigning the result of a computation, then the object only
exists once, so
z<- 0+1 gets NAMED==1.
However, if the computation is done by returning a named value from within
a function, as in
f<- function(){v<- 1+0; v}
z<- f()
then again NAMED==2. This is because the side effects of the function
_might_ result in something having a hold on the function environment,
e.g. if we had
e<- NULL
f<- function(){e<<-environment(); v<- 1+0; v}
z<- f()
then z[1]<- 5 would change e$v too. As it happens, there aren't any side
effects in the forme case, but R loses track and assumes the worst.