From murdoch at stats.uwo.ca  Tue Oct 13 13:59:34 2009
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Tue, 13 Oct 2009 07:59:34 -0400
Subject: [Rd] unexpected behavior in list of lexical closures (PR#14004)
In-Reply-To: <20091013055009.8B36B282EFEA@mail.pubhealth.ku.dk>
References: <20091013055009.8B36B282EFEA@mail.pubhealth.ku.dk>
Message-ID: <4AD46BA6.4030102@stats.uwo.ca>

On 13/10/2009 1:50 AM, elliott.forney at gmail.com wrote:
> Full_Name: Elliott Forney
> Version: 2.9.2
> OS: Linux, Fedora 10
> Submission from: (NULL) (129.82.47.235)

This is not a bug, just a consequence of lazy evaluation.  Arguments are 
not evaluated when passed, but when first used.  Since the "input" 
argument is never evaluated in the commented version of "funk" below, it 
isn't evaluated until one of the output functions is evaluated.

It's a good practice to force the evaluation of arguments to function 
builders like this, for exactly the reason you saw.  (The force() 
function is one way to do it, but any expression evaluating the argument 
will work.

Duncan Murdoch


> 
> 
> The following code creates a list of functions that are lexically closed over a
> single argument.  If a print statement is included then each function in the
> list evaluates to a different value.  If the print statement is not included
> then each function evaluates to something different, as expected.  I am
> convinced that this behavior is not correct as one would not expect the presence
> of a lone print statement to alter the behavior of a program.
> 
> Please let me know if you have any questions and thank you for your time.  The
> sample code follows:
> 
> ## returns a function that sums input with 5
> funk <- function(input)
> {
>   ## expected behavior if either of
>   ## the following lines is uncommented
>   # print(input)
>   # input <- input
> 
>   ## function to sum input with 5
>   ## lexical closure over input
>   function()
>   {
>     input + 5
>   }
> }
> 
> ## create a list different funk's
> funk.list <- list()
> for (i in 1:5)
> {
>   ## just some values to sum over
>   test.vector <- 1:i
> 
>   ## add funk that sums test.vector with 5
>   funk.list[[i]] <- funk(sum(test.vector))
> }
> 
> ## print result of evaluating each funk
> ## They are all the same unless print or
> ## reflexive assignment is uncommented!!
> for (i in 1:5)
>   print(funk.list[[i]]())
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] unexpected behavior in list of lexical closures (PR#14004)
Duncan Murdoch