[R] I don't understand this
Richard A. O'Keefe
ok at cs.otago.ac.nz
Wed Sep 3 04:14:19 CEST 2003
Thomas Lumley <tlumley at u.washington.edu> wrote:
I would have said that the behavior of
(if (cond) names else dim)(x) <- 10
is undefined in the S language, along with things like the order of
evaluation of the apply functions.
The thing is, it would make perfect sense for
(if (cond) f else g)(x) <- e
to have the effect of
(if (cond) f(x) <- e else g(x) <- e)
In fact, I've used two programming languages where the analogue of
this _did_ work, and a third where it didn't but using only published
interfaces could very easily be made to work.
Another assignment-related thing I'm not clear on is what
f(x) <<- e
is supposed to do.
f(x) <- e
is equivalent to
x <- "f<-"(x, value=e)
and
x <<- e
assigns to x in the next outer environment,
but a simple macro-expansion of
f(x) <<- e
to
x <<- "f<-"(x, value=e)
may have the nasty effect of writing to an outer x a value derived from
an inner one.
Now, that seems to be exactly what happens in R:
> x <- c(1,2,3)
> f <- function(x) x[2] <<- x
> f(77)
> x
[1] 77 77
While the documentation and source code _could_ tell me whether this
is intentional, as far as I can tell (and I have, needless to say,
looked) they _don't_.
Now, despite its misleading opening screen (which says that the
target of an assignment is "a variable name (possibly quoted)",
?"<<-" goes on to say that
vvv
In all the assignment operator expressions, `x' can be a name or
^^^
an expression defining a part of an object to be replaced (e.g.,
`z[[1]]'). The name does not need to be quoted, though it can be.
(the arrows are my emphasis.) So it's explict that f(x) <<- e is
*supposed* to be allowed and I don't need to ask about that.
The question is, what is f(x) <<- e supposed to do when there is an
x in the current environment as well as one in an outer environment?
It doesn't make much sense to fetch from one variable and store into
the other, but that's what R actually does. Is that really what's
*supposed* to happen?
It would be perfectly possible to make f(x) <<- e use the same
variable in both places, and since the form is accepted by R,
I expected it to work that way.
Perhaps the simplest alternative that would still allow this form
to be used in non-confusing cases would be to issue an error message
if x is defined in the local environment; if it isn't, the simple macro
expansion will work just fine.
> x <- c(1,2,3)
> f <- function(y) x[2] <<- y
> f(77)
> x
[1] 1 77 3
This example works as ?"<<-" might lead one to expect.
More information about the R-help
mailing list