1 minute read

How Mutable Is Data Anyway?�������������������������������������������������������������������������������������

Chapter 8 ■ More r prograMMing

If we return the function g from f rather than the result of evaluating it, we see another feature of R’s scoping—something called closures. R remembers the values of variables inside a function that we have returned from and that is no longer an active part of our computation. In the example below, we returned the function g at which point there is no longer an active f function. So there is not really an active instance of the parameter y any longer. Yet g refers to a y, so the parameter we gave to f is actually remembered.

Advertisement

x <- "x" f <- function(y) { g <- function() c(x, y) g

} g <- f("y") g() ## [1] "x" "y"

We can see how this works if we invoke f twice, with different values for parameter y:

x <- "x" f <- function(y) { g <- function() c(x, y) g

} g <- f("y") h <- f("z") g() ## [1] "x" "y" h() ## [1] "x" "z"

This creates two different functions. Inside f they are both called g, but they are two different functions because they are created in two different calls to f, and they remember two different y parameters because the two instances of f were invoked with different values for y.

When looking outward from the point where a function is defined, it is looking for the values of variables at the time a function is invoked, not the values at the time where the function is created. Variables do not necessarily have to be defined at the time the function is created; they just need to be defined when the function is eventually invoked.

Consider this code:

f <- function() { g <- function() c(y, z) y <- "y" g

} h <- f() h() ## Error in h(): object 'z' not found z <- "z" h() ## [1] "y" "z"

225

This article is from: