unexpected scoping behavior with functions created in a loop

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

unexpected scoping behavior with functions created in a loop

Antonio, Fabio Di Narzo
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

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: unexpected scoping behavior with functions created in a loop

Gabor Grothendieck
The missing item is lazy evaluation.  Try forcing the evaluation of i
and then repeat:

makeF <- function(i) { force(i); function() i }


On Sat, Dec 6, 2008 at 9:22 PM, Antonio, Fabio Di Narzo
<[hidden email]> 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
>
> ______________________________________________
> [hidden email] 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.
>

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

Re: unexpected scoping behavior with functions created in a loop

Antonio, Fabio Di Narzo
2008/12/6 Gabor Grothendieck <[hidden email]>:
> 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
> <[hidden email]> 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
>>
>> ______________________________________________
>> [hidden email] 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

______________________________________________
[hidden email] 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.
Reply | Threaded
Open this post in threaded view
|

lazy evaluation and scoping ?

Bert Gunter
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: [hidden email] [mailto:[hidden email]] On
Behalf Of Antonio, Fabio Di Narzo
Sent: Saturday, December 06, 2008 7:28 PM
To: Gabor Grothendieck
Cc: [hidden email]
Subject: Re: [R] unexpected scoping behavior with functions created in a
loop

2008/12/6 Gabor Grothendieck <[hidden email]>:
> 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
> <[hidden email]> 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
>>
>> ______________________________________________
>> [hidden email] 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

______________________________________________
[hidden email] 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.

______________________________________________
[hidden email] 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.