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