Murat Tasan
2013-Aug-14 23:47 UTC
[Rd] local variable assignment: first copies from higher frame?
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
Peter Meilstrup
2013-Aug-15 02:19 UTC
[Rd] local variable assignment: first copies from higher frame?
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 [[alternative HTML version deleted]]