<p>Knowledge of the way how R evaluates expressions is crucial to avoid hours of staring at the screen or hitting unexpected and difficult bugs.</p>
<p>We’ll start with an example of an issue I came accross a few months ago when using the <code>purrr::map</code> function. To simplify, the issue I had:</p>
<p><label for="wat">⊕</label><span><img src="https://i0.wp.com/appsilondatascience.com/blog//assets/article_images/2017-10-30-r-function-evaluation/wat.jpg?w=456" data-recalc-dims="1"><br>wat</span></p>
<figure>
<pre><code data-lang="r"><span>makePrintFunction</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>index</span><span>)</span><span> </span><span>{</span><span>
</span><span>function</span><span>()</span><span> </span><span>{</span><span>
</span><span>print</span><span>(</span><span>index</span><span>)</span><span>
</span><span>}</span><span>
</span><span>}</span><span>
</span><span>printFunctions</span><span> </span><span>&lt;-</span><span> </span><span>lapply</span><span>(</span><span>1</span><span>:</span><span>3</span><span>,</span><span> </span><span>function</span><span>(</span><span>i</span><span>)</span><span> </span><span>makePrintFunction</span><span>(</span><span>i</span><span>))</span><span>
</span><span>printFunctions</span><span>[[</span><span>2</span><span>]]()</span><span>
</span><span># 2
</span><span>
</span><span>printFunctions</span><span> </span><span>&lt;-</span><span> </span><span>purrr</span><span>::</span><span>map</span><span>(</span><span>1</span><span>:</span><span>3</span><span>,</span><span>
</span><span>function</span><span>(</span><span>i</span><span>)</span><span> </span><span>makePrintFunction</span><span>(</span><span>i</span><span>))</span><span>
</span><span>printFunctions</span><span>[[</span><span>2</span><span>]]()</span><span>
</span><span>#</span><span> </span><span>3</span></code></pre>
</figure>
<p>Since I came across the issue, <code>purrr::map</code> <a rel="nofollow" href="https://github.com/tidyverse/purrr/commit/b041e7897bc882037b7b5044a53e585c217a9b5a" target="_blank">has changed</a> and this example no longer applies. To simulate it, let’s use a simplified implementation of <code>map</code> function. You should be able to just copy-paste the code in this article and run it:</p>
<figure>
<pre><code data-lang="r"><span>map</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>range</span><span>,</span><span> </span><span>functionToApply</span><span>)</span><span> </span><span>{</span><span>
</span><span>result</span><span> </span><span>&lt;-</span><span> </span><span>vector</span><span>(</span><span>&quot;list&quot;</span><span>,</span><span> </span><span>length</span><span>(</span><span>range</span><span>))</span><span>
</span><span>for</span><span> </span><span>(</span><span>i</span><span> </span><span>in</span><span> </span><span>range</span><span>)</span><span> </span><span>{</span><span>
</span><span>result</span><span>[[</span><span>i</span><span>]]</span><span> </span><span>&lt;-</span><span> </span><span>functionToApply</span><span>(</span><span>i</span><span>)</span><span>
</span><span>}</span><span>
</span><span>return</span><span>(</span><span>result</span><span>)</span><span>
</span><span>}</span><span>
</span><span>makePrintFunction</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>index</span><span>)</span><span> </span><span>{</span><span>
</span><span>function</span><span>()</span><span> </span><span>{</span><span>
</span><span>print</span><span>(</span><span>index</span><span>)</span><span>
</span><span>}</span><span>
</span><span>}</span><span>
</span><span>printFunctions</span><span> </span><span>&lt;-</span><span> </span><span>lapply</span><span>(</span><span>1</span><span>:</span><span>3</span><span>,</span><span> </span><span>function</span><span>(</span><span>i</span><span>)</span><span> </span><span>makePrintFunction</span><span>(</span><span>i</span><span>))</span><span>
</span><span>printFunctions</span><span>[[</span><span>2</span><span>]]()</span><span>
</span><span># 2
</span><span>
</span><span>printFunctions</span><span> </span><span>&lt;-</span><span> </span><span>map</span><span>(</span><span>1</span><span>:</span><span>3</span><span>,</span><span> </span><span>function</span><span>(</span><span>i</span><span>)</span><span> </span><span>makePrintFunction</span><span>(</span><span>i</span><span>))</span><span>
</span><span>printFunctions</span><span>[[</span><span>2</span><span>]]()</span><span>
</span><span>#</span><span> </span><span>3</span></code></pre>
</figure>
<hr>
<p><strong>How to fix that?<strong></strong></strong></p>
<p>If you don’t already know to fix that issue, you’ll quickly find out. This is quite a common problem and the solution is to use the <code>force</code> function as follows:</p>
<figure>
<pre><code data-lang="r"><span>makePrintFunction</span><span> </span><span>&lt;-</span><span> </span><span>function</span><span>(</span><span>index</span><span>)</span><span> </span><span>{</span><span>
</span><span>force</span><span>(</span><span>index</span><span>)</span><span>
</span><span>function</span><span>()</span><span> </span><span>{</span><span>
</span><span>print</span><span>(</span><span>index</span><span>)</span><span>
</span><span>}</span><span>
</span><span>}</span><span>
</span><span>printFunctions</span><span> </span><span>&lt;-</span><span> </span><span>lapply</span><span>(</span><span>1</span><span>:</span><span>3</span><span>,</span><span> </span><span>function</span><span>(</span><span>i</span><span>)</span><span> </span><span>makePrintFunction</span><span>(</span><span>i</span><span>))</span><span>
</span><span>printFunctions</span><span>[[</span><span>2</span><span>]]()</span><span>
</span><span># 2
</span><span>
</span><span>printFunctions</span><span> </span><span>&lt;-</span><span> </span><span>map</span><span>(</span><span>1</span><span>:</span><span>3</span><span>,</span><span> </span><span>function</span><span>(</span><span>i</span><span>)</span><span> </span><span>makePrintFunction</span><span>(</span><span>i</span><span>))</span><span>
</span><span>printFunctions</span><span>[[</span><span>2</span><span>]]()</span><span>
</span><span>#</span><span> </span><span>2</span></code></pre>
</figure>
<hr>
<p><strong>It works! But … why?<strong></strong></strong></p>
<p>This could be a great moment to just carry on – the problem is solved. You’ve heard about lazy evaluation and know that <code>force()</code> is useful in fixing such issues. But then again, what does lazy evaluation mean in this context?</p>
<p>Let’s take a look at the magical <code>force</code> function. It consists of two lines:</p>
<p><label for="Huh?">⊕</label><span><img src="https://i0.wp.com/appsilondatascience.com/blog//assets/article_images/2017-10-30-r-function-evaluation/whaa.jpg?w=456" data-recalc-dims="1"><br>Huh?</span></p>
<figure>
<pre><code data-lang="r"><span>force</span><span>
</span><span># function (x) # x
# </span></code></pre></figure>