Many thanks to both Duncan and Bert for clarifying this. Having looked carefully at what you both wrote, my conclusion is the following:
in this code below f <- function(x) {function() {x}} b <- lapply(1:3, f) lapply does not actually call f with the values 1, 2, and 3. Instead, it calls f three times with the same object that, had only f used x for something, would have evaluated to 1 in the first call and to 2 in the second etc. but since f does not use x, the expression passed to f is never actually evaluated until the first time one of the functions in b is called. But at that point, that object will evaluate to 3 for all three functions in b. so what lapply is doing resembles: > z <- 1; i <- f(z); z <-2; j <- f(z); z <- 3; k <- f(z); b <- list(i, j, k) > b[[1]]() [1] 3 > b[[2]]() [1] 3 > b[[3]]() [1] 3 Thanks again! /Ali On Tue, Apr 24, 2012 at 18:37, Duncan Murdoch <murdoch.dun...@gmail.com> wrote: > On 12-04-24 5:13 PM, Ali Tofigh wrote: >> >> On Tue, Apr 24, 2012 at 16:57, Duncan Murdoch<murdoch.dun...@gmail.com> >> wrote: >>>> >>>> I thought that >>>> lapply calls f three times and returns a list with whatever f >>>> returned. Is this not so? >>> >>> >>> That is so. In each case, f creates a function that looks in its >>> enclosing >>> environment for the variable x to be returned. >>> >>> That enclosing environment is the evaluation frame of f, where x is the >>> argument being passed. >>> >>> But x is never used in evaluating f, so the promise to evaluate x is >>> never >>> forced until you finally call one of those functions. >>> >>> That means x will refer to some internal variable in lapply (which sapply >>> calls). You'll have 3 different promises to evaluate it, but they all >>> evaluate to the same value. >> >> >> Thank you Duncan for you reply! However, I'm not sure I understand >> this last explanation. This is what I think you mean lapply does. >> Pleas correct me if I'm wrong. >> >> 1) lapply uses the same variable name as the argument in my function >> (in this case 'x') > > > No, lapply can use any name it likes, or no name at all (e.g. just an > expression like 1+y). > > >> 2) lapply uses this 'x' variable to set up a bunch of unevaluated calls > > > No, lapply calls f a bunch of times, passing this expression each time. > > >> 3) finally, lapply evaluates all the calls. but at this point, >> lapply's 'x' variable is set to the last element of the list that was >> passed to it and all the unevaluated calls will now use this value as >> their 'x'? > > > When lapply evaluates f, it produces a function that refers to the local > variable x in each evaluation frame. That's a different variable each time, > but in all cases it's a promise to evaluate the expression that lapply > passed in. So if lapply passed 1+y as the expression, x becomes a promise > to evaluate 1+y in lapply's evaluation frame. > > Since you don't call any of those functions until after lapply is done, its > evaluation frame will remain. It's hard to get to it, but each of those > promises references it. > > When you finally evaluate x in one of those functions, it goes and evaluates > 1+y in the lapply frame (or whatever the expression was). That evaluates to > 3. It could have evaluated to 17 if lapply had done something stupid like > setting y to 16 after calling f in the loop, but R functions never do stupid > things, so you don't need to worry about that. > > Duncan Murdoch ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.