On Fri, May 17, 2013 at 2:47 AM, Duncan Murdoch <murdoch.dun...@gmail.com>wrote:
> On 13-05-16 11:17 PM, Peter Meilstrup wrote: > >> On Thu, May 16, 2013 at 6:06 AM, McGehee, Robert < >> Robert.McGehee@geodecapital.**com <robert.mcge...@geodecapital.com>> >> wrote: >> >> Duncan, Thank you for the clarification on how delayedAssign works. >>> Should >>> R-level interfaces to promise objects ever become available, I expect >>> they >>> would at time come in handy. >>> >>> On the subject of substitute and delayedAssign, I do have a follow-up >>> question for the list. I'm trying to convert a named list of expression >>> objects into an environment of promise objects. After conversion, each >>> expression in the list will be automatically evaluated when the variable >>> with the same name is accessed in the environment. Effectively, I'm >>> trying >>> to create a hash table of promise objects. >>> >>> >> Populating a new environment with promises happens to be what "calling a >> function" in R does anyway, so an elegant way to accomplish this goal is: >> >> makePromiseEnv <- function(expressions, parent=parent.frame()) { >> f <- function() environment() >> formals(f) <- as.pairlist(expressions) >> environment(f) <- parent >> f() >> } >> >> e <- makePromiseEnv(alist(a = {print("hello"); 4}, b = {print("again"); >>> >> 6})) >> >>> e$a >>> >> [1] "hello" >> [1] 4 >> >>> e$a >>> >> [1] 4 >> >>> e$b >>> >> [1] "again" >> [1] 6 >> >>> e$b >>> >> [1] 6 >> >> > I like that solution, except for one thing: I don't see an easy way to > control the environment where those expressions will be executed. Since > you've set them as defaults on the arguments, they will be evaluated in the > evaluation frame of f(), and that might not be what we want. An obvious > example of the problem would be > > e <- makePromiseEnv(alist(a = ls())) > > I don't know what Robert would want > > e$a > > to print, but one somewhat natural version would be to have it evaluate > the ls() in the environment from which makePromiseEnv was called, i.e. the > global environment in this case. Neither your solution nor mine do this, > but I can see how to modify mine, since it makes the evaluation environment > of the expression explicit. Can you see a modification that would do that > with your approach? > > Duncan Murdoch > Sure, you could pass the expressions as arguments to f instead of as the defaults. In this case do.call does the construction of promises. makePromiseEnv2 <- function(expressions, envir=parent.frame()) { f <- function() environment() arglist <- expressions arglist[] <- list(quote(expr=)) #delete defaults, keep names formals(f) <- as.pairlist(arglist) do.call(f, expressions, envir=envir) } e <- makePromiseEnv2(alist(a=ls())) [[alternative HTML version deleted]] ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel