2

I am using lapply to make new functions and noticed that that sometimes it returns what is expected, and sometimes it returns only copies of the lastly created function.

Here is an example for the illustration, consider that I want to make the following simple list of functions

listFuncs = lapply( 1:3, function(X){ 
  myfunc = function(y){X+y}
  myfunc
})

Unfortunately, a simple evaluation shows that I am not getting what I hoped

listFuncs[[1]](10)
[1] 13
listFuncs[[2]](10)
[1] 13

Indeed, the list only contains the function

myfunc = function(y){3+y}

However, if I output something during the creation of the functions, for example

listFuncs = lapply( 1:3, function(X){ 
  myfunc = function(y){X+y}
  print(myfunc(0)) ## NEW LINE HERE !!!
  myfunc
})

then my list of functions is "as expected"

[1] 1
[1] 2
[1] 3
> listFuncs[[1]](10)
[1] 11
> listFuncs[[2]](10)
[1] 12

Does anyone understand what is going on ? By advance, thank you.

user149575
  • 23
  • 3
  • 2
    The is not a bug, it's a feature. Study the concept of "lazy evaluation". – Roland Mar 29 '15 at 14:03
  • @Roland I was surprised by the long discussion on r-devel beginning [here](https://stat.ethz.ch/pipermail/r-devel/2015-February/070686.html) that seemed to include serious consideration for the position that this is a bug (by Radford, at least). It was the first time I'd ever seen "official" folks entertain that idea. – joran Mar 29 '15 at 14:23
  • It looks like Radford Neal and Jeroen Ooms were the only ones calling it a bug, and neither of them is official; Neal obviously understands R deeply, but he often disagrees with R-core. – Ben Bolker Mar 29 '15 at 14:45
  • @BenBolker I took Luke et al's opennes to changing the behavior (or at least discussing it) to be a tacit admission of it at least being undesirable. – joran Mar 29 '15 at 19:45

1 Answers1

3

You can use the force function:

listFuncs = lapply( 1:3, 
    function(X) { 
        force(X)
        myfunc <- function(y) { X+y }
        myfunc
    }
)
listFuncs[[1]](10) ## 11
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453