title: R optim(): unexpected behavior when working with parent environments
body: <p>Consider the function <code>fn()</code> which stores the most recent input <code>x</code> and its return value <code>ret &lt;- x^2</code> in the parent environment. </p>
  
  <pre><code>makeFn &lt;- function(){
      xx &lt;- ret &lt;- NA
      fn &lt;- function(x){
         if(!is.na(xx) &amp;&amp; x==xx){
             cat("x=", xx, ", ret=", ret, " (memory)", fill=TRUE, sep="")
             return(ret)
         }
         xx &lt;&lt;- x; ret &lt;&lt;- sum(x^2)
         cat("x=", xx, ", ret=", ret, " (calculate)", fill=TRUE, sep="")
         ret
      }
      fn
  }
  fn &lt;- makeFn()
  </code></pre>
  
  <p><code>fn()</code> only does the calculation when a different input value is provided. Otherwise, it reads <code>ret</code> from the parent environment. </p>
  
  <pre><code>fn(2)
  # x=2, ret=4 (calculate)
  # [1] 4
  fn(3)
  # x=3, ret=9 (calculate)
  # [1] 9
  fn(3)
  # x=3, ret=9 (memory)
  # [1] 9
  </code></pre>
  
  <p>When plugin <code>fn()</code> into <code>optim()</code> to find its minimum, the following unexpected behavior results:</p>
  
  <pre><code>optim(par=10, f=fn, method="L-BFGS-B")
  # x=10, ret=100 (calculate)
  # x=10.001, ret=100.02 (calculate)
  # x=9.999, ret=100.02 (memory)
  # $par
  # [1] 10
  # 
  # $value
  # [1] 100
  #
  # (...)
  </code></pre>
  
  <p><b>Is this a bug? How can this happen?</b></p>
  
  <p>Even when using the C-API of R, I have a hard time to imagine how this behavior can be achieved. Any ideas?</p>
  
  <hr>
  
  <p><b>Note:</b> </p>
  
  <ul>
  <li><p>works:</p>
  
  <pre><code>library("optimParallel") # (parallel) wrapper to optim(method="L-BFGS-B")
  cl &lt;- makeCluster(2); setDefaultCluster(cl)
  optimParallel(par=10, f=fn)
  </code></pre></li>
  <li><p>works:</p>
  
  <pre><code>optimize(f=fn, interval=c(-10, 10))
  </code></pre></li>
  <li><p>works:</p>
  
  <pre><code>optim(par=10, fn=fn)
  </code></pre></li>
  <li><p>fails:</p>
  
  <pre><code>optim(par=10, fn=fn, method="BFGS")
  </code></pre></li>
  <li><p>works:</p>
  
  <pre><code>library("lbfgs"); library("numDeriv")
  lbfgs(call_eval=fn, call_grad=function(x) grad(func=fn, x=x), vars=10)
  </code></pre></li>
  <li><p>works:</p>
  
  <pre><code>library("memoise")
  fn_mem &lt;- memoise(function(x) x^2)
  optim(par=10, f=fn_mem, method="L-BFGS-B")
  </code></pre></li>
  <li><p>Tested with R version 3.5.0.</p></li>
  </ul>