R is commonly thought of as a functional programming language. If you associate functional programming (FP) with lambda calculus and pure FP languages like Haskell, then you may get surprised by aspects of R’s computational model. One of these has to do with R’s lazy evaluation mechanism, in particular the concept of “promise objects” (as pointed out by some, R passes a promise, not a value).
Here’s a simple program to illustrate what I mean.
add <- function(x) { function(y) x + y }
adders <- lapply(1:10, add)
What would you expect to be the answer for the following two queries?
adders[[1]](10)
adders[[10]](10)
It turns out both evaluate to 20, when one expects 11 and 20!
Contrary to what one would expect from lambda calculus, the x in the closure of both adders[[1]] and adders[[10]] are bound to 10, the last value of the vector 1:10, as seen below:
as.list(environment(adders[[1]]))
$x
[1]10
as.list(environment(adders[[1]]))
$x
[1]10
There is further discussion of this issue at http://stackoverflow.com/questions/29084193/how-to-not-fall-into-rs-lazy-evaluation-trap