Strange Interaction Between Promises and Closures (PR#13861)
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" And here's my version output (I'm running the version in Debian lenny):
version
_ platform x86_64-pc-linux-gnu arch x86_64 os linux-gnu system x86_64, linux-gnu status major 2 minor 7.1 year 2008 month 06 day 23 svn rev 45970 language R version.string R version 2.7.1 (2008-06-23) --Keith