From ggrothendieck at gmail.com  Fri Mar  7 21:47:17 2008
From: ggrothendieck at gmail.com (Gabor Grothendieck)
Date: Fri, 7 Mar 2008 15:47:17 -0500
Subject: [Rd] merging environments
In-Reply-To: <f8e6ff050803071215t60361eacqba698d332a574e20@mail.gmail.com>
References: <47D1912A.3010802@zoo.ufl.edu>
	<f8e6ff050803071215t60361eacqba698d332a574e20@mail.gmail.com>
Message-ID: <971536df0803071247i585ba6a3g37c9cb6d2985c1ac@mail.gmail.com>

On Fri, Mar 7, 2008 at 3:15 PM, hadley wickham <h.wickham at gmail.com> wrote:
> 2008/3/7 Ben Bolker <bolker at zoo.ufl.edu>:
> >
>
> >    Despite the spirited arguments of various R-core folks
> >  who feel that mle() doesn't need a "data" argument, and
> >  that users would be better off learning to deal with function
> >  closures, I am *still* trying to make such things work
> >  in a reasonably smooth fashion ...
> >
> >    Is there a standard idiom for "merging" environments?
> >  i.e., suppose a function has an environment that I want
> >  to preserve, but _add_ the contents of a data list --
> >  would something like this do it? Is there a less ugly
> >  way?
> >
> >  x <- 0
> >  y <- 1
> >  z <- 2
> >
> >  f <- function() {
> >      x+y+z
> >  }
> >
> >  f2 <- function(fun,data) {
> >      L <- ls(pos=environment(fun))
> >      mapply(assign,names(data),data,
> >                       MoreArgs=list(envir=environment(fun)))
> >      print(ls(pos=environment(fun)))
> >  }
> >
> >  f2(f,list(a=1))
>
> I think you're doomed to be ugly if you don't use closures - I think
> any explicit manipulation of environments is worse than the implicit
> manipulation by closures.
>
> f <- function(data) with(data, x + y + z)
> f2 <- function(fun, data) function() fun(data)
>
> f2(f, list(x = 10))()
>
> Although it would be even nicer if you could do:
>
> f <- function()  x + y + z
> f2 <- function(fun, data) function() with(data, fun())


This last one is close to what you can do with proto and is referred
to as the method of proxies here:
http://r-proto.googlecode.com/files/prototype_approaches.pdf

f <- function() x + y + z
f2 <- function(fun, ...) with(proto(environment(fun), ..., g = fun), g())
f2(f, x = 1, y = 2, z = 3)

The proto call creates an anonymous proto object whose parent is
the parent of fun.  The anonymous proto object contains the ...
arguments to f2 and g.    g is just fun with its environment reset to
the anonymous proto object. We then call g.



[Rd] merging environments
Gabor Grothendieck