From maechler at stat.math.ethz.ch  Tue Apr  4 17:11:24 2006
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Tue, 4 Apr 2006 17:11:24 +0200
Subject: [Rd] Return function from function with minimal environment
In-Reply-To: <443284E5.2050105@jhsph.edu>
References: <59d7961d0604040640i5b055b47mfb84d1c746e2ef27@mail.gmail.com>
	<443284E5.2050105@jhsph.edu>
Message-ID: <17458.35996.501722.419233@stat.math.ethz.ch>

>>>>> "Roger" == Roger D Peng <rpeng at jhsph.edu>
>>>>>     on Tue, 04 Apr 2006 10:38:29 -0400 writes:

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

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

yes, but for now, and for the given purpose,
also as seen in examples, such as  splinefun() or approxfun(),
just rm() the things  you don't want in the environment.
I.e.,

 foo <- function(huge) {
    scale <- mean(huge)
    rm(huge)
    function(x) { scale * x }
 }


Martin

    Roger> -roger

    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> -- 
    Roger> Roger D. Peng  |  http://www.biostat.jhsph.edu/~rpeng/

    Roger> ______________________________________________
    Roger> R-devel at r-project.org mailing list
    Roger> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] Return function from function with minimal environment
Martin Maechler