Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The best way to find what is going on is to tell the compiler to output its intermediate representation with <code>-v4</code>. The output is voluminous and a bit hard to read, but should allow you to find out exactly what the difference in the generated code is, and how the compiler arrived there.</p> <p>You will probably notice that <code>fA</code> is being moved outside the function (to the "global scope") on your first example. On your second example, it probably is not (meaning it will be recreated on each call).</p> <p>One possible reason for it not being moved outside the function would be because the compiler is thinking it depends on the value of <code>n</code>. On your working example, there is no <code>n</code> for <code>fA</code> to depend on.</p> <p>But the reason I think the compiler is avoiding moving <code>fA</code> outside on your second example is because it is trying to avoid a space leak. Consider what would happen if <code>fA</code>, instead of your array, were an infinite list (on which you used the <code>!!</code> operator). Imagine you called it once with a large number (for instance <code>f 10000</code>), and later only called it with small numbers (<code>f 2</code>, <code>f 3</code>, <code>f 12</code>...). The 10000 elements from the earlier call are still on memory, wasting space. So, to avoid this, the compiler creates <code>fA</code> again every time you call your function.</p> <p>The space leak avoidance probably does not happen on your first example because in that case <code>f</code> is in fact only called once, returning a closure (we are now at the frontier of the pure functional and the imperative worlds, so things get a bit more subtle). This closure replaces the original function, which will never be called again, so <code>fA</code> is only called once (and thus the optimizer feels free to move it outside the function). On your second example, <code>f</code> does not get replaced by a closure (since its value depends on the argument), and thus will get called again.</p> <p>If you want to try to understand more of this (which will help reading the <code>-v4</code> output), you could take a look at the <a href="http://research.microsoft.com/~simonpj/Papers/spineless-tagless-gmachine.ps.gz" rel="noreferrer">Spineless Tagless G-Machine</a> paper (<a href="http://citeseer.ist.psu.edu/peytonjones92implementing.html" rel="noreferrer">citeseer link</a>).</p> <p>As to your final question, I think it is a compiler peculiarity (but I could be wrong). However, it would not surprise me if all compilers did the same thing, even if it were not part of the language.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload