[R] lazy evaluation and scoping ?
Bert Gunter
gunter.berton at gene.com
Mon Dec 8 20:19:09 CET 2008
I think actually it's both lazy evaluation and scoping. Here is how I
understand it.
Consider:
> flist <- vector("list",2) ## creates the empty list
> for(i in 1:2)slist[[i]] <- function()i
Now the RHS of the assignment is a function that returns the value of i.
That is:
> flist
function()i
<environment: 0x04e3af4c>
[[2]]
function()i
<environment: 0x04e3ae18>
So the question is: what will be the value of i when the function is
invoked? By R's lexical scoping rules it will be the value of i in the
enclosing environment of the function, which is the value of i in the
environment when the function is **defined** . This will be i = 2, the last
value of the for loop on exit. This is due to lazy evaluation -- the value
of i is not needed until the for() ends, as one can find by:
> sapply(flist,function(z)as.list(environment(z)))
$i
[1] 2
$i
[1] 2
Hence one gets the results you originally saw. Adding the force(i) statement
forces i to be evaluated separately at each iteration of the loop, thus
placing the current values of i at each iteration into each function's
enclosing environment.
HTH.
-- Bert Gunter
-----Original Message-----
From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On
Behalf Of Antonio, Fabio Di Narzo
Sent: Saturday, December 06, 2008 7:28 PM
To: Gabor Grothendieck
Cc: r-help at r-project.org
Subject: Re: [R] unexpected scoping behavior with functions created in a
loop
2008/12/6 Gabor Grothendieck <ggrothendieck at gmail.com>:
> The missing item is lazy evaluation. Try forcing the evaluation of i
> and then repeat:
>
> makeF <- function(i) { force(i); function() i }
Tnx! That works! Sometimes lazy evaluation + side effects is just too
much (complicated) for me:D
bests,
a.
>
>
> On Sat, Dec 6, 2008 at 9:22 PM, Antonio, Fabio Di Narzo
> <antonio.fabio at gmail.com> wrote:
>> Hi guys.
>> I recently stumbled on an unexpected behavior of R when using
>> functions created in a loop.
>> The problem is silly enough to me that I had hard time choosing a good
>> mail subject, not talking about searching in the archives...
>> After some experiments, I trimmed down the following minimal
>> reproducible example:
>> #######
>> makeF <- function(i) function() i
>>
>> fList <- list(makeF(1), makeF(2))
>> sapply(fList, do.call, list())
>> ##This works as expected (by me...):
>> #[1] 1 2
>>
>> ##Things go differently when creating functions in a for loop:
>> for(i in 1:2)
>> fList[[i]] <- makeF(i)
>> sapply(fList, do.call, list())
>> #[1] 2 2
>>
>> ##Same result with "lapply":
>> fList <- lapply(as.list(1:2), makeF)
>> sapply(fList, do.call, list())
>> #[1] 2 2
>> #######
>>
>> I evidently overlook some important detail, but I still can't get it.
>> Somebody can explain me what's happening there?
>> Bests,
>> antonio.
>>
>>> R.version
>> _
>> platform i686-pc-linux-gnu
>> arch i686
>> os linux-gnu
>> system i686, linux-gnu
>> status Patched
>> major 2
>> minor 8.0
>> year 2008
>> month 12
>> day 04
>> svn rev 47063
>> language R
>> version.string R version 2.8.0 Patched (2008-12-04 r47063)
>> --
>> Antonio, Fabio Di Narzo
>> Ph.D. student at
>> Department of Statistical Sciences
>> University of Bologna, Italy
>>
>> ______________________________________________
>> R-help at 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.
>>
>
--
Antonio, Fabio Di Narzo
Ph.D. student at
Department of Statistical Sciences
University of Bologna, Italy
______________________________________________
R-help at 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.
More information about the R-help
mailing list