title: Unexpected forcing when evaluating substituted expression in nested function
body: <p>Inspecting how R's promises work, I recognized an effect that I cannot explain. Consider the following code:</p>
  
  <pre><code>twice3 &lt;- function(i) {
    eval.subst &lt;- function() eval(substitute(i))
  
    print("one")
    substitute(i)
    print("two")
    eval(substitute(i))
    print("three")
    eval(substitute(i))
    print("four")
    eval.subst()
    print("five")
    eval.subst()
  }
  </code></pre>
  
  <p>This should test a varietey of things that happen when I try to evaluate the expression in a promise, without forcing the promise itself. Here's what I got:</p>
  
  <pre><code>&gt; twice3({print("hi"); 10})
  [1] "one"
  [1] "two"
  [1] "hi"
  [1] "three"
  [1] "hi"
  [1] "four"
  [1] "hi"
  [1] "five"
  [1] 10
  </code></pre>
  
  <p>Observations:</p>
  
  <ul>
  <li><code>substitute</code> alone does not evaluate or force anything.</li>
  <li><code>eval(substitute(i))</code> also does not force the original promise, which I expected. It probably gets out the expression and evaluates it, without touching the value part of <code>i</code>.</li>
  <li><code>eval.subst</code>, however, which was supposed to do the same thing as <code>eval(substitute(i))</code>, <em>does</em> show some unexpected caching. At first, I supposed that only concerned its return value, however...</li>
  <li>As we see after <code>"five"</code>, the calling of <code>eval.subst</code> has evaluated <code>i</code> at that point. </li>
  </ul>
  
  <p>Why is the last effect happening? The only way I could explain it would be that inside <code>eval.subst</code>, <code>i</code> refers to a closed over thing, and not "directly" to the outside <code>i</code>; but in any case, if I substitute first, why would that change anything?</p>
  
  <hr>
  
  <p><strong>TL;DR</strong> What explains the difference here:</p>
  
  <pre><code>&gt; f1 &lt;- function(i) {
  +   eval.subst &lt;- function() eval(substitute(i))
  +   print('one')
  +   eval.subst()
  +   print('two')
  +   i
  + }
  &gt; f1({print('hi'); 10})
  [1] "one"
  [1] "hi"
  [1] "two"
  [1] 10
  
  &gt; f2 &lt;- function(i) {
  +   print('one')
  +   eval(substitute(i))
  +   print('two')
  +   i
  + }
  &gt; f2({print('hi'); 10})
  [1] "one"
  [1] "hi"
  [1] "two"
  [1] "hi"
  [1] 10
  </code></pre>