kb...@andrew.cmu.edu wrote:
Full_Name: Keith Bare
Version: 2.7.1
OS: Linux
Submission from: (NULL) (128.2.134.48)


I observed unexpected behavior attempting to use lapply to vary parameters in
generated closures.  All the generated closures ran with the last parameter
value in the list.

Here's a simple example:

funcs <- lapply(c("alpha", "beta", "gamma", "delta"), function(x) function()
print(x))
funcs[[1]]()
[1] "delta"
funcs[[2]]()
[1] "delta"
funcs[[3]]()
[1] "delta"
funcs[[4]]()
[1] "delta"


What appears to be happening, is that the unevaluated promise for x is getting
stored in the generated closure.  This promise references a variable in the
local environment for the lapply call.  However, that variable gets clobbered by
subsequent processing by lapply.


This may be a language "feature" rather than a bug.  But IMO, the observed
behavior is very non-intuitive.  If so, maybe it deserves mention in the
documentation for lapply, "function", or the language reference section on
functions.


For now, I've found that adding a force in the function that generates the
returned closure is a workaround.  E.g.:

funcs <- lapply(c("alpha", "beta", "gamma", "delta"), function(x) { force(x);
function() print(x) })
funcs[[1]]()
[1] "alpha"
funcs[[2]]()
[1] "beta"
funcs[[3]]()
[1] "gamma"
funcs[[4]]()
[1] "delta"

Not a bug, consequence of lazy evaluation, and force() IS the workaround. It is not specific to lapply; a prototypical example goes

> f <- function(x) function() x
> x <- 2
> g <- f(x)
> x <- 4
> g()
[1] 4
> x <- 6
> g()
[1] 4

In the lapply context, the promise refers to an internal loop variable, and if the promise is not evaluated until the loop is done, you get the value of the loop variable at the end.

Documenting this sort of thing in a place that actually gets seen is an interesting problem... Probably, Section 4.3.3 in the R-lang manual is the only viable option.


--
   O__  ---- Peter Dalgaard             Ă˜ster Farimagsgade 5, Entr.B
  c/ /'_ --- Dept. of Biostatistics     PO Box 2099, 1014 Cph. K
 (*) \(*) -- University of Copenhagen   Denmark      Ph:  (+45) 35327918
~~~~~~~~~~ - (p.dalga...@biostat.ku.dk)              FAX: (+45) 35327907

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to