From rpeng at jhsph.edu  Tue Apr  4 16:38:29 2006
From: rpeng at jhsph.edu (Roger D. Peng)
Date: Tue, 04 Apr 2006 10:38:29 -0400
Subject: [Rd] Return function from function with minimal environment
In-Reply-To: <59d7961d0604040640i5b055b47mfb84d1c746e2ef27@mail.gmail.com>
References: <59d7961d0604040640i5b055b47mfb84d1c746e2ef27@mail.gmail.com>
Message-ID: <443284E5.2050105@jhsph.edu>

In R 2.3.0-to-be, I think you can do

foo <- function(huge) {
	scale <- mean(huge)
	g <- function(x) { scale * x }
	environment(g) <- emptyenv()
	g
}

-roger

Henrik Bengtsson wrote:
> Hi,
> 
> this relates to the question "How to set a former environment?" asked
> yesterday.  What is the best way to to return a function with a
> minimal environment from a function? Here is a dummy example:
> 
> foo <- function(huge) {
>   scale <- mean(huge)
>   function(x) { scale * x }
> }
> 
> fcn <- foo(1:10e5)
> 
> The problem with this approach is that the environment of 'fcn' does
> not only hold 'scale' but also the memory consuming object 'huge',
> i.e.
> 
> env <- environment(fcn)
> ll(envir=env)  # ll() from R.oo
> #   member data.class dimension object.size
> # 1   huge    numeric   1000000     4000028
> # 2  scale    numeric         1          36
> 
> save(env, file="temp.RData")
> file.info("temp.RData")$size
> # [1] 2007624
> 
> I generate quite a few of these and my 'huge' objects are of order
> 100Mb, and I want to keep memory usage as well as file sizes to a
> minimum.  What I do now, is to remove variable from the local
> environment of 'foo' before returning, i.e.
> 
> foo2 <- function(huge) {
>   scale <- mean(huge)
>   rm(huge)
>   function(x) { scale * x }
> }
> 
> fcn <- foo2(1:10e5)
> env <- environment(fcn)
> ll(envir=env)
> #   member data.class dimension object.size
> # 1  scale    numeric         1          36
> 
> save(env, file="temp.RData")
> file.info("temp.RData")$size
> # [1] 156
> 
> Since my "foo" functions are complicated and contains many local
> variables, it becomes tedious to identify and remove all of them, so
> instead I try:
> 
> foo3 <- function(huge) {
>   scale <- mean(huge);
>   env <- new.env();
>   assign("scale", scale, envir=env);
>   bar <- function(x) { scale * x };
>   environment(bar) <- env;
>   bar;
> }
> 
> fcn <- foo3(1:10e5)
> 
> But,
> 
> env <- environment(fcn)
> save(env, file="temp.RData");
> file.info("temp.RData")$size
> # [1] 2007720
> 
> When I try to set the parent environment of 'env' to emptyenv(), it
> does not work, e.g.
> 
> fcn(2)
> # Error in fcn(2) : attempt to apply non-function
> 
> but with the new.env(parent=baseenv()) it works fine. The "base"
> environment has the empty environment as a parent.  So, I try to do
> the same myself, i.e. new.env(parent=new.env(parent=emptyenv())), but
> once again I get
> 
> fcn(2)
> # Error in fcn(2) : attempt to apply non-function
> 
> Apparently, I do not understand enough here.  Please, enlighten me. In
> the meantime I stick with foo2().
> 
> Best,
> 
> Henrik
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 

-- 
Roger D. Peng  |  http://www.biostat.jhsph.edu/~rpeng/



[Rd] Return function from function with minimal environment
Roger D. Peng