Hi everybody, with the following code I generate a list of functions. Each function reflects a "condition". When I evaluate this list of functions by another lapply/sapply, I get an unexpected result: all values coincide. However, when I uncomment the print(), it works as expected. Is this a bug or a feature? conditions <- 1:4 test <- lapply(conditions, function(mycondition){ #print(mycondition) myfn <- function(i) mycondition*i return(myfn) }) sapply(test, function(myfn) myfn(2)) Cheers, Daniel -- Daniel Kaschek Institute of Physics Freiburg University Room 210 Phone: +49 761 2038531
On Mon, Feb 23, 2015 at 12:57 PM, Daniel Kaschek <daniel.kaschek at physik.uni-freiburg.de> wrote:> Is this a bug or a feature?I think it is a bug. If we use substitute to inspect the promise, it appears the index number is always equal to its last value: vec <- c("foo", "bar", "baz") test <- lapply(vec, function(x){ function(){x} }) substitute(x, environment(test[[1]])) substitute(x, environment(test[[2]]))
Use force() (or anything that evaluates mycondition, e.g. your print): function(mycondition) { force(mycondition) function(i) mycondition * i } within the lapply() loop. Not a bug, but does surprise people. It is lazy evaluation. D. On 2/23/15 12:57 PM, Daniel Kaschek wrote:> Hi everybody, > > with the following code I generate a list of functions. Each function > reflects a "condition". When I evaluate this list of functions by > another lapply/sapply, I get an unexpected result: all values coincide. > However, when I uncomment the print(), it works as expected. Is this a > bug or a feature? > > conditions <- 1:4 > test <- lapply(conditions, function(mycondition){ > #print(mycondition) > myfn <- function(i) mycondition*i > return(myfn) > }) > > sapply(test, function(myfn) myfn(2)) > > > > Cheers, > Daniel >-- Director, Data Sciences Initiative, UC Davis Professor, Dept. of Statistics, UC Davis http://datascience.ucdavis.edu http://www.stat.ucdavis.edu/~duncan
Greetings! I thought it was a lazy evaluation thing. I added "force" around mycondition and everything worked as expected. Cheers! On Mon Feb 23 2015 at 1:47:20 PM Jeroen Ooms <jeroenooms at gmail.com> wrote:> On Mon, Feb 23, 2015 at 12:57 PM, Daniel Kaschek > <daniel.kaschek at physik.uni-freiburg.de> wrote: > > Is this a bug or a feature? > > I think it is a bug. If we use substitute to inspect the promise, it > appears the index number is always equal to its last value: > > vec <- c("foo", "bar", "baz") > test <- lapply(vec, function(x){ > function(){x} > }) > substitute(x, environment(test[[1]])) > substitute(x, environment(test[[2]])) > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]
On 23/02/2015 3:57 PM, Daniel Kaschek wrote:> Hi everybody, > > with the following code I generate a list of functions. Each function > reflects a "condition". When I evaluate this list of functions by > another lapply/sapply, I get an unexpected result: all values coincide. > However, when I uncomment the print(), it works as expected. Is this a > bug or a feature? >Arguments aren't evaluated until they are used. The force() function can be used to force evaluation when you want it. This is a feature: it allows you to have arguments that are never evaluated, because they are never used, or defaults that depend on things that are calculated within the function. Duncan Murdoch> conditions <- 1:4 > test <- lapply(conditions, function(mycondition){ > #print(mycondition) > myfn <- function(i) mycondition*i > return(myfn) > }) > > sapply(test, function(myfn) myfn(2)) > > > > Cheers, > Daniel >
On Mo, 2015-02-23 at 16:54 -0500, Duncan Murdoch wrote:> This is a feature: it allows you to have arguments that are never > evaluated, because they are never used, or defaults that depend on > things that are calculated within the function.I haven't thought about the thing with the default arguments. That's really a feature. Thanks, Daniel> > Duncan Murdoch > > > > conditions <- 1:4 > > test <- lapply(conditions, function(mycondition){ > > #print(mycondition) > > myfn <- function(i) mycondition*i > > return(myfn) > > }) > > > > sapply(test, function(myfn) myfn(2)) > > > > > > > > Cheers, > > Daniel > > >-- Daniel Kaschek Institute of Physics Freiburg University Room 210 Phone: +49 761 2038531