Skip to content
Prev 381200 / 398500 Next

static vs. lexical scope

I found this confusing until I learned about environments. The current state of the environment that was active at the time the function was defined is searched, not a frozen copy of the enclosing environment as it existed at the time the function was defined.

x <- 1 # as it was when f was created
f <- function () {
  a <- x # x not yet in current environment
  x <- 2 # always modifies current environment
  b <- x # finds the definition nearest along the enclosing environments list
  c(a=a, b=b)
}
x <- 3 # change after f was created
f()
## a b
## 3 2
x # changes within function don't affect enclosing or calling environments
## [1] 3

Duncan refers to "evaluation frame" (a term described in the R Language Definition) but I tend to think of a "current environment" and two linked lists of supplementary environments: the search path of `parent.env`()s (a.k.a. enclosing environments built from the current environments that were active when functions were defined) and the call chain of `parent.frame`()s (function environments that were active at the point functions were called). You can almost forget about the parent.frame chain unless you are creating your own non-standard evaluation functions (like `with` or `subset`)... 

Environments mutate over time. Specifically, the list of enclosing environments doesn't change but the variables in them do.

(Credit to Hadley Wickham's Advanced R, criticisms to me.)
On September 26, 2019 7:58:57 AM PDT, Duncan Murdoch <murdoch.duncan at gmail.com> wrote: