From murdoch.duncan at gmail.com  Fri May 17 11:47:29 2013
From: murdoch.duncan at gmail.com (Duncan Murdoch)
Date: Fri, 17 May 2013 05:47:29 -0400
Subject: [Rd] Substitute / delayedAssign (was: Substitute unaware when
 promise objects are evaluated)
In-Reply-To: <CAJoaRhb4cWxx6PhCO1vzajHaa9q2pNA40Y+OvxnCW3XMKt2FPg@mail.gmail.com>
References: <17B09E7789D3104E8F5EEB0582A8D66FF25D00C072@MSGRTPCCRF2WIN.DMN1.FMR.COM>
	<CAJoaRhb4cWxx6PhCO1vzajHaa9q2pNA40Y+OvxnCW3XMKt2FPg@mail.gmail.com>
Message-ID: <5195FCB1.30109@gmail.com>

On 13-05-16 11:17 PM, Peter Meilstrup wrote:
> On Thu, May 16, 2013 at 6:06 AM, McGehee, Robert <
> Robert.McGehee at 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



[Rd] Substitute / delayedAssign (was: Substitute unaware when promise objects are evaluated)
Duncan Murdoch