hi all -- this might not be the correct list for this
question/discussion, though R-help didn't seem like the correct venue,
either, so...
i'm looking for just some extra clarification of how local variables
are defined/bound, beyond the simple cases given in the Language
document.
the particular instance is when there is variable assignment inside a function.
normally, this creates a local variable, but there appears to be an
additional preceding step that does a bit more: the local variable is
initialized to the value of any same-named variable bound in a
containing frame.
in a sense, the lexical scoping rule is first applied to acquire a
value, and this value is then applied to the new local variable, and
is then immediately changed by the assignment operation.
i only noticed this when assigning variables to entries within a
'list' structure, like so:
tempf <- function(x, local = TRUE)
{
executing_environment <- environment()
closure_environment <- parent.env(executing_environment)
print(executing_environment)
cat(str(mget("my_list", envir = executing_environment, inherits =
FALSE, ifnotfound = NA)[[1]]))
print(closure_environment)
cat(str(mget("my_list", envir = closure_environment, inherits =
FALSE, ifnotfound = NA)[[1]]))
if(local) {
my_list$x <- x
} else {
my_list$x <<- x
}
print(executing_environment)
cat(str(mget("my_list", envir = executing_environment, inherits =
FALSE, ifnotfound = NA)[[1]]))
print(closure_environment)
cat(str(mget("my_list", envir = closure_environment, inherits =
FALSE, ifnotfound = NA)[[1]]))
}
my_list <- list(x = 1, y = 2)
tempf(0, local = TRUE)
<environment: 0xcb47cb8>
logi NA
<environment: R_GlobalEnv>
List of 2
$ x: num 1
$ y: num 2
<environment: 0xcb47cb8>
List of 2
$ x: num 0
$ y: num 2
<environment: R_GlobalEnv>
List of 2
$ x: num 1
$ y: num 2
tempf(0, local = FALSE)
<environment: 0xbf4df50>
logi NA
<environment: R_GlobalEnv>
List of 2
$ x: num 1
$ y: num 2
<environment: 0xbf4df50>
logi NA
<environment: R_GlobalEnv>
List of 2
$ x: num 0
$ y: num 2
what surprised me in the first "local = TRUE" case is that 'y' is
still 2 in the executing environment.
so, i think my question comes down to this: when a new local variable
is created in an assignment operation, is the full value of any
matching variable in a containing frame first copied to the new local
variable?
and if so, was this chosen as a strategy specifically to allow for
these sorts of "indexed" assignment operations? (where i'm assigning
to only a single location within the vector object)?
and finally, are the other entries in the vector fully copied over, or
are they treated as "promises" similar to formal parameters, albeit
now as single entries within a containing vector?
thanks for any help on digging down a bit on the implementation here!
-murat
ah, that makes perfect sense in the functional programming sense of things.
thanks!
On Wed, Aug 14, 2013 at 10:19 PM, Peter Meilstrup
<peter.meilstrup at gmail.com> wrote:
Not anything that complicated -- your answer is in the R language definition
under 'Subset assignment' and the part in "Function calls" that describes
assignment functions.
Whenever a call is found on the left side of a `<-`, it is munged by
sticking a "<-" on the function name and pulling out the first argument. So
my_list$x <- x
which is syntactically equivalent to
`$`(my_list, x) <- x
is effectively transformed into something like:
my_list <- `$<-`(my_list, x, x)
The function `$<-` gets its argument from wherever it is found, and returns
a modified version.
Peter