Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's a running example in pseudo-javascript-like syntax.</p> <pre><code>function f(x) { var y = ...; function g(z) { function h(w) { .... y, z, w .... } .... x, h .... } .... x, g .... } </code></pre> <p>One representation is a linked chain of environments. That is, a closure consists of a code pointer, some slots, and a reference to the enclosing closure or the top-level environment. In this representation,</p> <pre><code>f = [&lt;code&gt;, &lt;top-level-env&gt;] g = [&lt;code&gt;, f, x, y] h = [&lt;code&gt;, g, z] </code></pre> <p>except sometimes it's better to let every function have a direct reference to the top-level environment, since it's used so often:</p> <pre><code>f = [&lt;code&gt;, &lt;top-level-env&gt;] g = [&lt;code&gt;, &lt;top-level-env&gt;, f, x, y] h = [&lt;code&gt;, &lt;top-level-env&gt;, g, z] </code></pre> <p>(There are other variations too.)</p> <p>One advantage of this representation is that you can store mutable variables right in the closure. (Well, maybe, depending on how you represent function activations.) One disadvantage is some variables may take multiple hops to reach, if you have deeply nested closures. Another disadvantage is that if a closure outlives its parent (eg, <code>g</code> returns <code>h</code>) then this representation might prevent the GC from collecting environment frames that are mostly or even completely unreachable.</p> <p>Another representation is "flat closures": each closure contains a code pointer and slots for all of the code's free variables.</p> <pre><code>g = [&lt;code&gt;, x, y] h = [&lt;code&gt;, y, z] </code></pre> <p>This representation fixes the space/GC problem; no closure pins another closure in memory. On the other hand, free-variable slots are copied instead of shared, so if there is a nested closure with many free variables---or many instances of a nested closure---overall memory usage might be higher. Also, this representation typically requires storage for mutable variables to be heap-allocated (but only for variables that are actually mutated and only when the mutation cannot be automatically rewritten).</p> <p>There are also hybrid approaches. For example, you might have mostly-flat closures but treat the top-level environment specially:</p> <pre><code>g = [&lt;code&gt;, &lt;top-level-env&gt;, x, y] </code></pre> <p>Or you might have a "sufficiently clever" (or at least "sufficiently ambitious") compiler that tries to pick between representations based on number of free variables, nesting depth, etc.</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. 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.
 

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