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

2013-05-17 Thread Duncan Murdoch

On 13-05-16 11:17 PM, Peter Meilstrup wrote:

On Thu, May 16, 2013 at 6:06 AM, McGehee, Robert 
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

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2013-05-17 Thread Peter Meilstrup
On Fri, May 17, 2013 at 2:47 AM, Duncan Murdoch murdoch.dun...@gmail.comwrote:

 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


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

2013-05-17 Thread peter dalgaard

On May 16, 2013, at 15:06 , McGehee, Robert 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.
 
 Here's the code I wrote that works just fine.
 
 x - list(a=3, b=expression(a+2), sleep=expression(Sys.sleep(2)))
 env - new.env()
 for (i in seq(x)) {
   key - names(x)[i]
   .Internal(delayedAssign(key,
  eval(substitute(x[[i]], list(x=x, 
 i=i)))[[1]],
  eval.env=env, assign.env=env))
 } 
 env$b # 3+2
 [1] 5
 env$sleep # Sleeps for 2 seconds
 NULL  
 
 The problem is that R CMD check complains that I shouldn't be using 
 .Internal() to access the delayedAssign function. However, if I don't use 
 .Internal(), then delayedAssign puts another substitute around my call that 
 prevents the 'i' iterator variable from being evaluated at the correct time, 
 which causes all variables to get the value x[[i]] for the very last value of 
 'i'.
 
 Can I safely ignore this R CMD check warning about .Internal, or is there a 
 better way to write this code?

These things are slippery, but the usual way out is to figure out exactly which 
expression you want to call, compute the expression unevaluated, and evaulate 
it.

Something like

e - bquote(delayedAssign( .(names(x)[i]), .(x[[i]]), eval.env=env, 
assign.env=env))
print(e)
eval(e)

(of course remove the print(e) once you're sure that it is doing the right 
thing)



 
 Thanks, Robert
 
 
 
 -Original Message-
 From: Duncan Murdoch [mailto:murdoch.dun...@gmail.com] 
 Sent: Wednesday, May 15, 2013 6:04 PM
 To: McGehee, Robert
 Cc: R-Devel (r-devel@r-project.org)
 Subject: Re: [Rd] Substitute unaware when promise objects are evaluated
 
 On 13-05-15 11:54 AM, McGehee, Robert wrote:
 R-devel,
 I used the 'substitute' function to create labels for objects inside an 
 environment, without actually evaluating the objects, as the objects might 
 be promises.
 
 However, I was surprised to see that 'substitute' returns the expression 
 slot of the original promise even after the promise has been forcibly 
 evaluated. (Doesn't the promise go away after evaluation?) This behavior 
 probably falls under the ...no guarantee that the resulting expression 
 makes any sense clause of the ?substitute documentation, but in case 
 there's something actually wrong here, I thought I'd send an example.
 
 I think you misunderstand promises.
 
 A promise has two (or three, depending how you count) parts:  an 
 expression with an associated environment, and a value.  The value isn't 
 filled in until the expression is evaluated, but the expression doesn't 
 go away then.  You can still see it until you change the variable that 
 holds the promise.
 
 
 Here's an example showing how the evaluated expression returned by 
 substitute does not match the actual variable value:
 
 env - new.env()
 z - 0
 delayedAssign(var, z+2, assign.env=env)
 substitute(var, env=env)
 z + 2
 
 The documentation for substitute may not be clear on this, but for a 
 promise, the env argument will be ignored.  It was the eval.env argument 
 to delayedAssign that set the promise's environment.
 
 force(env$var)
 [1] 2
 z - 10
 substitute(var, env=env)
 z + 2
 eval(substitute(var, env=env))
 [1] 12
 force(env$var)
 [1] 2
 
 Is there any obvious way to code around this behavior, e.g. can I explicitly 
 check if an object in an environment is an unevaluated promise?
 
 Not at R level. In C code you could, but you probably shouldn't.  Think 
 of promises as values where you can look up the expression that gave the 
 value, and sometimes delay the calculation until you need it.
 
 Duncan Murdoch
 
 __
 R-devel@r-project.org mailing list
 https://stat.ethz.ch/mailman/listinfo/r-devel

-- 
Peter Dalgaard, Professor
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Email: pd@cbs.dk  Priv: pda...@gmail.com

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2013-05-16 Thread Duncan Murdoch

On 16/05/2013 9:06 AM, McGehee, Robert 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.

Here's the code I wrote that works just fine.

x - list(a=3, b=expression(a+2), sleep=expression(Sys.sleep(2)))
env - new.env()
for (i in seq(x)) {
key - names(x)[i]
.Internal(delayedAssign(key,
   eval(substitute(x[[i]], list(x=x, 
i=i)))[[1]],
   eval.env=env, assign.env=env))
}   
env$b # 3+2
[1] 5
env$sleep # Sleeps for 2 seconds
NULL

The problem is that R CMD check complains that I shouldn't be using 
.Internal() to access the delayedAssign function. However, if I don't use .Internal(), 
then delayedAssign puts another substitute around my call that prevents the 'i' iterator 
variable from being evaluated at the correct time, which causes all variables to get the 
value x[[i]] for the very last value of 'i'.

Can I safely ignore this R CMD check warning about .Internal, or is there a 
better way to write this code?


You should never call .Internal.  Arguments to internal functions may 
change without notice.


Here's one way to write your example without it.

x - list(a=3, b=expression(a+2), sleep=expression(Sys.sleep(2)))
env - new.env()

mydelay - function(i) {
  expr - x[[i]]
  name - names(x)[i]
  do.call(delayedAssign, list(x=name, value=substitute(eval(expr), 
list(expr=expr)),

  eval.env=env, assign.env=env))
}

for (i in seq(x)) mydelay(i)

Duncan Murdoch




Thanks, Robert



-Original Message-
From: Duncan Murdoch [mailto:murdoch.dun...@gmail.com]
Sent: Wednesday, May 15, 2013 6:04 PM
To: McGehee, Robert
Cc: R-Devel (r-devel@r-project.org)
Subject: Re: [Rd] Substitute unaware when promise objects are evaluated

On 13-05-15 11:54 AM, McGehee, Robert wrote:
 R-devel,
 I used the 'substitute' function to create labels for objects inside an 
environment, without actually evaluating the objects, as the objects might be 
promises.

 However, I was surprised to see that 'substitute' returns the expression slot of the 
original promise even after the promise has been forcibly evaluated. (Doesn't the promise go 
away after evaluation?) This behavior probably falls under the ...no guarantee that 
the resulting expression makes any sense clause of the ?substitute documentation, but 
in case there's something actually wrong here, I thought I'd send an example.

I think you misunderstand promises.

A promise has two (or three, depending how you count) parts:  an
expression with an associated environment, and a value.  The value isn't
filled in until the expression is evaluated, but the expression doesn't
go away then.  You can still see it until you change the variable that
holds the promise.


 Here's an example showing how the evaluated expression returned by substitute 
does not match the actual variable value:

 env - new.env()
 z - 0
 delayedAssign(var, z+2, assign.env=env)
 substitute(var, env=env)
 z + 2

The documentation for substitute may not be clear on this, but for a
promise, the env argument will be ignored.  It was the eval.env argument
to delayedAssign that set the promise's environment.

 force(env$var)
 [1] 2
 z - 10
 substitute(var, env=env)
 z + 2
 eval(substitute(var, env=env))
 [1] 12
 force(env$var)
 [1] 2

 Is there any obvious way to code around this behavior, e.g. can I explicitly 
check if an object in an environment is an unevaluated promise?

Not at R level. In C code you could, but you probably shouldn't.  Think
of promises as values where you can look up the expression that gave the
value, and sometimes delay the calculation until you need it.

Duncan Murdoch


__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


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

2013-05-16 Thread Peter Meilstrup
On Thu, May 16, 2013 at 6:06 AM, McGehee, Robert 
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

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel