McGehee, Robert
2013-May-15 15:54 UTC
[Rd] Substitute unaware when promise objects are evaluated
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. 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> 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? Thanks, Robert> R.version_ platform x86_64-pc-linux-gnu arch x86_64 os linux-gnu system x86_64, linux-gnu status major 3 minor 0.0 year 2013 month 04 day 03 svn rev 62481 language R version.string R version 3.0.0 (2013-04-03) nickname Masked Marvel Robert McGehee, CFA Geode Capital Management, LLC One Post Office Square, 28th Floor | Boston, MA | 02109 Direct: (617)392-8396
Duncan Murdoch
2013-May-15 22:03 UTC
[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 + 2The 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
Apparently Analagous Threads
- Substitute / delayedAssign (was: Substitute unaware when promise objects are evaluated)
- Error condition in evaluating a promise
- Using substitute to access the expression related to a promise
- delayedAssign changing values
- A doubt about substitute() after delayedAssign()