[R] Lexical scoping question

Thomas Lumley tlumley at u.washington.edu
Fri Feb 28 18:28:03 CET 2003


On Fri, 28 Feb 2003, Jim Rogers wrote:

> Hello,
>
> Could someone please tell me what I am thinking about incorrectly:
>
> f <- function(y) {
>   g <- function(x) x + y
>   g
> }
>
> In the following, I get what I expect based on my understanding of
> lexical scoping:
>
> (f(1))(3) # 4
> (f(2))(3) # 5
>
> But now,
>
> fs <- lapply(c(1, 2), f)
> fs[[1]](3) # 5  (Why not 4 ?)
> fs[[2]](3) # 5
>
>
> Checking the environments of these functions, I see that "y" is indeed
> bound to the value 2 in both cases:
>
> es <- lapply(fs, environment)
> ys <- lapply(es, function(env) get("y", env)) # list(2, 2)
>

Because that's the way it works.  It's a wart caused by the
interaction of lazy evaluation and lexical scoping.  The problem is that
`y' is not evaluated until you actually call an element of fs.

You can do


  force<-function(z) z

 f <- function(y) {
   force(y)
   g <- function(x) x + y
   g
 }

which will work as you expect.  IIRC Luke Tierney has added force() to
the forthcoming R1.7.0.

You could also do
 f <- function(y) {
   y
   g <- function(x) x + y
   g
 }

but that makes less visual sense.


	-thomas




More information about the R-help mailing list