On 12-04-24 4:22 PM, Ali Tofigh wrote:
This has been asked before, but I just cannot figure out why lapply
should behave this way given that R uses lazy evalution. Even after
reading (or at least trying to read) parts of the R language
definition.
f<- function(x) {function() {x}}
a<- list(f(1), f(2), f(3))
a[[1]]() # as expected
[1] 1
a[[2]]() # as expected
[1] 2
a[[3]]() # as expected
[1] 3
b<- sapply(1:3, f)
b[[1]]() # why?
[1] 3
b[[2]]() # why?
[1] 3
b[[3]]() # expected, kind of...
[1] 3
Now I know that if I force the evaluation of x inside my function f,
that the behaviour will change, i.e., b[[1]]() will return the value 1
etc. But could some knowledgeable person please tell me how the lazy
evaluation as implemented in R results in, what I preceive to be, a
very strange behaviour when using lapply as above? I thought that
lapply calls f three times and returns a list with whatever f
returned. Is this not so?
That is so. In each case, f creates a function that looks in its
enclosing environment for the variable x to be returned.
That enclosing environment is the evaluation frame of f, where x is the
argument being passed.
But x is never used in evaluating f, so the promise to evaluate x is
never forced until you finally call one of those functions.
That means x will refer to some internal variable in lapply (which
sapply calls). You'll have 3 different promises to evaluate it, but
they all evaluate to the same value.
You will get the result you want by forcing evaluation of x in f. Then
the three promises get evaluated before the internal value gets changed.
f<- function(x) { force(x); function() {x}}
b<- sapply(1:3, f)
b[[1]]() # gives 1
You should almost always force evaluation of arguments before returning
a constructed function to avoid problems like you had.
Duncan Murdoch
______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.