OSDN Git Service

Minor edits.
authorSimon Forman <sforman@hushmail.com>
Wed, 27 Jun 2018 23:31:00 +0000 (16:31 -0700)
committerSimon Forman <sforman@hushmail.com>
Wed, 27 Jun 2018 23:31:00 +0000 (16:31 -0700)
docs/Types.html
docs/Types.ipynb
docs/Types.md
docs/Types.rst
docs/sphinx_docs/_build/html/notebooks/Types.html
docs/sphinx_docs/_build/html/notebooks/index.html
docs/sphinx_docs/_build/html/searchindex.js
docs/sphinx_docs/notebooks/Types.rst
test/test_type_inference.py

index e7bf01a..6486b06 100644 (file)
@@ -11775,11 +11775,8 @@ div#notebook {
 </div>
 <div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h1 id="Type-Inference">Type Inference<a class="anchor-link" href="#Type-Inference">&#182;</a></h1><p>This notebook presents a simple type inferencer for Joy code.  It can infer the stack effect of most Joy expressions.  It built largely by means of existing ideas and research (some of it may be original but I'm not able to say, as I don't fully understand the all of the source material in the depth required to make that call.)  A great overview of the existing knowledge is a talk <a href="http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/">"Type Inference in Stack-Based Programming Languages"</a> given by Rob Kleffner on or about 2017-03-10 as part of a course on the history of programming languages.</p>
-<p>The notebook starts with a simple inferencer based on the work of Jaanus Pöial which we then progressively elaborate to cover more Joy semantics.  Along the way we write a simple "compiler" that emits Python code for what I like to call Yin functions.</p>
-<p>Yin functions are those that only rearrange values in stacks, as opposed to Yang functions that actually work on the values themselves.  It's interesting to note that a Joy with <em>only</em> stacks (no other kinds of values) can be made and is Turing-complete, therefore all Yang functions are actually Yin functions, and all computation can be performed by manipulations of structures of containers, which is a restatement of the Laws of Form.  (Also, this implies that every program can be put into a form such that it can be computed in a single step, although that step may be enormous or unending.)</p>
-<p>Although I haven't completed it yet, a Joy based on Laws of Form provides the foundation for a provably correct computing system "down to the metal".  This is my original and still primary motivation for developing Joy.  (I want a proven-correct Operating System for a swarm of trash-collecting recycler robots.  To trust it I have to implementment it myself from first principles, and I'm not smart enough to truly grok the existing literature and software, so I had to go look for and find LoF and Joy.  Now that I have the mental tools to build my robot OS I can get down to it.</p>
-<p>Anyhow, here's type inference...</p>
+<h1 id="Type-Inference">Type Inference<a class="anchor-link" href="#Type-Inference">&#182;</a></h1><p>This notebook presents a simple type inferencer for Joy code.  It can infer the stack effect of most Joy expressions.  It's built largely by means of existing ideas and research.  (A great overview of the existing knowledge is a talk <a href="http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/">"Type Inference in Stack-Based Programming Languages"</a> given by Rob Kleffner on or about 2017-03-10 as part of a course on the history of programming languages.)</p>
+<p>The notebook starts with a simple inferencer based on the work of Jaanus Pöial which we then progressively elaborate to cover more Joy semantics.  Along the way we write a simple "compiler" that emits Python code for what I like to call Yin functions.  (Yin functions are those that only rearrange values in stacks, as opposed to Yang functions that actually work on the values themselves.)</p>
 
 </div>
 </div>
@@ -12027,7 +12024,7 @@ w/ {
 </div>
 <div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h3 id="Functions-on-Lists">Functions on Lists<a class="anchor-link" href="#Functions-on-Lists">&#182;</a></h3><p>These are slightly tricky.</p>
+<h3 id="Functions-on-Stacks">Functions on Stacks<a class="anchor-link" href="#Functions-on-Stacks">&#182;</a></h3><p>These are slightly tricky.</p>
 
 <pre><code>rest ( [1 ...] -- [...] )
 
@@ -12341,18 +12338,12 @@ cons ( 1 [...] -- [1 ...] )</code></pre>
     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
 
-    <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
-        <span class="k">return</span> <span class="n">s</span>
-
     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
-        <span class="k">return</span> <span class="n">s</span>
-
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
-        <span class="k">return</span> <span class="n">s</span>
 
-    <span class="k">return</span> <span class="bp">False</span>
+    <span class="k">return</span> <span class="n">s</span>
 </pre></div>
 
 </div>
@@ -12852,24 +12843,6 @@ cons ( 1 [...] -- [1 ...] )</code></pre>
 </div>
 </div>
 
-<div class="output_wrapper">
-<div class="output">
-
-
-<div class="output_area">
-
-<div class="prompt"></div>
-
-
-<div class="output_subarea output_stream output_stdout output_text">
-<pre>Cannot unify (1, 2) and (1001, 1002).
-</pre>
-</div>
-</div>
-
-</div>
-</div>
-
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
 </div>
@@ -12892,27 +12865,24 @@ cons ( 1 [...] -- [1 ...] )</code></pre>
         <span class="n">u</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">u</span><span class="p">)</span>
         <span class="n">v</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
 
-    <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
-        <span class="k">return</span> <span class="n">s</span>
-
     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
-        <span class="k">return</span> <span class="n">s</span>
 
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
-        <span class="k">return</span> <span class="n">s</span>
 
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
-        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>
-        <span class="k">for</span> <span class="n">uu</span><span class="p">,</span> <span class="n">vv</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">):</span>
-            <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">uu</span><span class="p">,</span> <span class="n">vv</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="bp">False</span><span class="p">:</span> <span class="c1"># (instead of a substitution dict.)</span>
-                <span class="k">break</span>
-        <span class="k">return</span> <span class="n">s</span>
-    <span class="k">return</span> <span class="bp">False</span>
+    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
+
+        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
+            <span class="c1"># Not a type error, caller passed in a bad value.</span>
+            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>  <span class="c1"># FIXME this message sucks.</span>
+
+        <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">),</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span> <span class="o">=</span> <span class="n">u</span><span class="p">,</span> <span class="n">v</span>
+        <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
+        <span class="k">if</span> <span class="n">s</span> <span class="o">!=</span> <span class="bp">False</span><span class="p">:</span>
+            <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
+
+    <span class="k">return</span> <span class="n">s</span>
 </pre></div>
 
 </div>
@@ -13973,7 +13943,7 @@ i0 &gt;= f0 -&gt; False
         <span class="k">pass</span>
 
     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
-        <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">])</span>
+        <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
         <span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
         <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
 
@@ -14009,7 +13979,7 @@ i0 &gt;= f0 -&gt; False
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>(((a0,), (a0, a0)), ((n0, n1), (n2,)))</pre>
+<pre>(((a1,), (a1, a1)), ((n1, n2), (n3,)))</pre>
 </div>
 
 </div>
@@ -14191,7 +14161,7 @@ i0 &gt;= f0 -&gt; False
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+<pre>ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
 cons = (a1 [.1.] -- [a1 .1.])
 divmod_ = (n2 n1 -- n4 n3)
 dup = (a1 -- a1 a1)
@@ -14208,13 +14178,13 @@ pred = (n1 -- n2)
 rest = ([a1 .1.] -- [.1.])
 rolldown = (a1 a2 a3 -- a2 a3 a1)
 rollup = (a1 a2 a3 -- a3 a1 a2)
-rrest = ([a0 a1 .0.] -- [.0.])
-second = ([a0 a1 .0.] -- a1)
-sqrt = (n0 -- n1)
+rrest = ([a1 a2 .1.] -- [.1.])
+second = ([a1 a2 .1.] -- a2)
+sqrt = (n1 -- n2)
 succ = (n1 -- n2)
 swap = (a1 a2 -- a2 a1)
-swons = ([.0.] a0 -- [a0 .0.])
-third = ([a0 a1 a2 .0.] -- a2)
+swons = ([.1.] a1 -- [a1 .1.])
+third = ([a1 a2 a3 .1.] -- a3)
 tuck = (a2 a1 -- a1 a2 a1)
 uncons = ([a1 .1.] -- a1 [.1.])
 </pre>
@@ -14270,7 +14240,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>((n0,), (n1,))</pre>
+<pre>((n1,), (n2,))</pre>
 </div>
 
 </div>
@@ -14313,7 +14283,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>(((a0, (a1, s0)), a2, a3, a4), ((a3, (a2, s0)),))</pre>
+<pre>(((a1, (a2, s1)), a3, a4, a5), ((a4, (a3, s1)),))</pre>
 </div>
 
 </div>
@@ -14344,7 +14314,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])
+<pre>([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])
 </pre>
 </div>
 </div>
@@ -14399,7 +14369,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(a0 a1 a2 -- a1 a0 a2)
+<pre>(a1 a2 a3 -- a2 a1 a3)
 </pre>
 </div>
 </div>
@@ -14431,7 +14401,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(a0 a1 a2 a3 -- a2 a3)
+<pre>(a1 a2 a3 a4 -- a3 a4)
 </pre>
 </div>
 </div>
@@ -14463,7 +14433,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(a0 a1 a2 -- a2 a1 a0)
+<pre>(a1 a2 a3 -- a3 a2 a1)
 </pre>
 </div>
 </div>
@@ -14529,9 +14499,9 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 <div class="output_subarea output_stream output_stdout output_text">
 <pre>def F(stack):
-    &#34;&#34;&#34;([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])&#34;&#34;&#34;
-    (a4, (a3, (a2, ((a0, (a1, s0)), stack)))) = stack
-    return ((a3, (a2, s0)), stack)
+    &#34;&#34;&#34;([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])&#34;&#34;&#34;
+    (a5, (a4, (a3, ((a1, (a2, s1)), stack)))) = stack
+    return ((a4, (a3, s1)), stack)
 </pre>
 </div>
 </div>
@@ -14572,9 +14542,9 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 <div class="output_subarea output_stream output_stdout output_text">
 <pre>def sqr(stack):
-    &#34;&#34;&#34;(n0 -- n1)&#34;&#34;&#34;
-    (n0, stack) = stack
-    return (n1, stack)
+    &#34;&#34;&#34;(n1 -- n2)&#34;&#34;&#34;
+    (n1, stack) = stack
+    return (n2, stack)
 </pre>
 </div>
 </div>
@@ -14642,7 +14612,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+<pre>ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
 cons = (a1 [.1.] -- [a1 .1.])
 dup = (a1 -- a1 a1)
 dupd = (a2 a1 -- a2 a2 a1)
@@ -14655,11 +14625,11 @@ popop = (a2 a1 --)
 rest = ([a1 .1.] -- [.1.])
 rolldown = (a1 a2 a3 -- a2 a3 a1)
 rollup = (a1 a2 a3 -- a3 a1 a2)
-rrest = ([a0 a1 .0.] -- [.0.])
-second = ([a0 a1 .0.] -- a1)
+rrest = ([a1 a2 .1.] -- [.1.])
+second = ([a1 a2 .1.] -- a2)
 swap = (a1 a2 -- a2 a1)
-swons = ([.0.] a0 -- [a0 .0.])
-third = ([a0 a1 a2 .0.] -- a2)
+swons = ([.1.] a1 -- [a1 .1.])
+third = ([a1 a2 a3 .1.] -- a3)
 tuck = (a2 a1 -- a1 a2 a1)
 uncons = ([a1 .1.] -- a1 [.1.])
 </pre>
@@ -14767,7 +14737,7 @@ uncons = ((a, Z), S) -- (Z, (a, S))</code></pre>
 </div>
 <div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<h4 id="compose()-version-2"><code>compose()</code> version 2<a class="anchor-link" href="#compose()-version-2">&#182;</a></h4><p>This function has to be modified to use the new datastructures and it is no longer recursive, instead recursion happens as part of unification.  Further, the first and second of Pöial's rules are now handled automatically by the unification algorithm.</p>
+<h4 id="compose()-version-2"><code>compose()</code> version 2<a class="anchor-link" href="#compose()-version-2">&#182;</a></h4><p>This function has to be modified to use the new datastructures and it is no longer recursive, instead recursion happens as part of unification.  Further, the first and second of Pöial's rules are now handled automatically by the unification algorithm.  (One easy way to see this is that now an empty stack effect comment is represented by a <code>StackJoyType</code> instance which is not "falsey" and so neither of the first two rules' <code>if</code> clauses will ever be <code>True</code>.  Later on I change the "truthiness" of <code>StackJoyType</code> to false to let e.g. <code>joy.utils.stack.concat</code> work with our stack effect comment cons-list tuples.)</p>
 
 </div>
 </div>
@@ -14846,7 +14816,7 @@ uncons = ((a, Z), S) -- (Z, (a, S))</code></pre>
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>((a0, s0), (s0, (a0, (a0, s0))))</pre>
+<pre>((a1, s1), (s1, (a1, (a1, s1))))</pre>
 </div>
 
 </div>
@@ -14860,7 +14830,7 @@ uncons = ((a, Z), S) -- (Z, (a, S))</code></pre>
 <div class="prompt input_prompt">In&nbsp;[67]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">),</span> <span class="n">uncons</span><span class="p">)</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="nb">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
 </pre></div>
 
 </div>
@@ -14879,7 +14849,7 @@ uncons = ((a, Z), S) -- (Z, (a, S))</code></pre>
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>((a0, (a1, s0)), (s0, (a1, (a0, (a0, (a1, s0))))))</pre>
+<pre>((a1, (a2, s1)), (s1, (a2, (a1, (a1, (a2, s1))))))</pre>
 </div>
 
 </div>
@@ -14986,7 +14956,7 @@ uncons = ((a, Z), S) -- (Z, (a, S))</code></pre>
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+<pre>ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
 cons = (a1 [.1.] -- [a1 .1.])
 divmod_ = (n2 n1 -- n4 n3)
 dup = (a1 -- a1 a1)
@@ -15003,15 +14973,15 @@ pred = (n1 -- n2)
 rest = ([a1 .1.] -- [.1.])
 rolldown = (a1 a2 a3 -- a2 a3 a1)
 rollup = (a1 a2 a3 -- a3 a1 a2)
-rrest = ([a0 a1 .0.] -- [.0.])
-second = ([a0 a1 .0.] -- a1)
-sqrt = (n0 -- n1)
+rrest = ([a1 a2 .1.] -- [.1.])
+second = ([a1 a2 .1.] -- a2)
+sqrt = (n1 -- n2)
 stack = (... -- ... [...])
 succ = (n1 -- n2)
 swaack = ([.1.] -- [.0.])
 swap = (a1 a2 -- a2 a1)
-swons = ([.0.] a0 -- [a0 .0.])
-third = ([a0 a1 a2 .0.] -- a2)
+swons = ([.1.] a1 -- [a1 .1.])
+third = ([a1 a2 a3 .1.] -- a3)
 tuck = (a2 a1 -- a1 a2 a1)
 uncons = ([a1 .1.] -- a1 [.1.])
 </pre>
@@ -15029,8 +14999,8 @@ uncons = ([a1 .1.] -- a1 [.1.])
     <div class="input_area">
 <div class=" highlight hl-ipython2"><pre><span></span><span class="k">print</span> <span class="p">;</span> <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack</span><span class="p">)</span>
 <span class="k">print</span> <span class="p">;</span> <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
-<span class="k">print</span> <span class="p">;</span> <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">),</span> <span class="n">uncons</span><span class="p">))</span>
-<span class="k">print</span> <span class="p">;</span> <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">),</span> <span class="n">cons</span><span class="p">))</span>
+<span class="k">print</span> <span class="p">;</span> <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="nb">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)))</span>
+<span class="k">print</span> <span class="p">;</span> <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="nb">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)))</span>
 </pre></div>
 
 </div>
@@ -15050,11 +15020,11 @@ uncons = ([a1 .1.] -- a1 [.1.])
 <pre>
 (... -- ... [...])
 
-(... a0 -- ... a0 a0 [...])
+(... a1 -- ... a1 a1 [...])
 
-(... a1 a0 -- ... a1 a0 a0 a1 [...])
+(... a2 a1 -- ... a2 a1 a1 a2 [...])
 
-(... a0 -- ... a0 [a0 ...])
+(... a1 -- ... a1 [a1 ...])
 </pre>
 </div>
 </div>
@@ -15085,7 +15055,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])
+<pre>(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])
 </pre>
 </div>
 </div>
@@ -15120,7 +15090,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>((s0, (a0, (a1, s1))), (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1)))</pre>
+<pre>((s1, (a1, (a2, s2))), (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2)))</pre>
 </div>
 
 </div>
@@ -15181,9 +15151,9 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 <div class="output_subarea output_stream output_stdout output_text">
 <pre>def Q(stack):
-    &#34;&#34;&#34;(... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])&#34;&#34;&#34;
-    (s0, (a0, (a1, s1))) = stack
-    return (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1))
+    &#34;&#34;&#34;(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])&#34;&#34;&#34;
+    (s1, (a1, (a2, s2))) = stack
+    return (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2))
 </pre>
 </div>
 </div>
@@ -15290,7 +15260,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(a0 [.0.] -- a0)
+<pre>(a1 [.1.] -- a1)
 </pre>
 </div>
 </div>
@@ -15321,7 +15291,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(a0 [.0.] -- [[a0 .0.] .1.])
+<pre>(a1 [.1.] -- [[a1 .1.] .2.])
 </pre>
 </div>
 </div>
@@ -15354,7 +15324,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>((s0, (a0, s1)), (a0, s0))</pre>
+<pre>((s1, (a1, s2)), (a1, s1))</pre>
 </div>
 
 </div>
@@ -15469,8 +15439,8 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(a1 -- a1 a1) (i1 i2 -- i3) (i0 -- i1)
-(a1 -- a1 a1) (f1 f2 -- f3) (f0 -- f1)
+<pre>(a1 -- a1 a1) (i1 i2 -- i3) (i1 -- i2)
+(a1 -- a1 a1) (f1 f2 -- f3) (f1 -- f2)
 </pre>
 </div>
 </div>
@@ -15509,7 +15479,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 <div class="prompt input_prompt">In&nbsp;[86]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
     <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
 </pre></div>
 
@@ -15527,8 +15497,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(f0 -- f1)
-(i0 -- i1)
+<pre>(n1 -- n2)
 </pre>
 </div>
 </div>
@@ -15542,7 +15511,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 <div class="prompt input_prompt">In&nbsp;[87]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
     <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
 </pre></div>
 
@@ -15560,7 +15529,8 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(n0 -- n1)
+<pre>(f1 -- f2)
+(i1 -- i2)
 </pre>
 </div>
 </div>
@@ -16116,8 +16086,8 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(f0 -- f1)
-(i0 -- i1)
+<pre>(f1 -- f2)
+(i1 -- i2)
 </pre>
 </div>
 </div>
@@ -16149,7 +16119,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>([n0* .0.] -- [n0* .0.] n0)
+<pre>([n1* .1.] -- [n1* .1.] n1)
 </pre>
 </div>
 </div>
@@ -16181,8 +16151,8 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(a0 [.0.] -- n0)
-(n0 [n0* .0.] -- n1)
+<pre>(a1 [.1.] -- n1)
+(n1 [n1* .1.] -- n2)
 </pre>
 </div>
 </div>
@@ -16218,7 +16188,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
 <div class="output_subarea output_stream output_stdout output_text">
-<pre>(a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n0 [n0* .0.] -- n1)
+<pre>(a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n1 [n1* .1.] -- n2)
 </pre>
 </div>
 </div>
@@ -16620,7 +16590,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[120]:</div>
+<div class="prompt input_prompt">In&nbsp;[115]:</div>
 <div class="inner_cell">
     <div class="input_area">
 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">expression</span> <span class="o">=</span> <span class="n">l2s</span><span class="p">([</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">,</span> <span class="n">mul</span><span class="p">])</span>
@@ -16633,10 +16603,10 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[121]:</div>
+<div class="prompt input_prompt">In&nbsp;[116]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="n">infer</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">expression</span>
 </pre></div>
 
 </div>
@@ -16649,13 +16619,13 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 <div class="output_area">
 
-<div class="prompt output_prompt">Out[121]:</div>
+<div class="prompt output_prompt">Out[116]:</div>
 
 
 
 
 <div class="output_text output_subarea output_execute_result">
-<pre>[]</pre>
+<pre>(n1, (n2, (mul, ())))</pre>
 </div>
 
 </div>
@@ -16666,100 +16636,220 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[116]:</div>
+<div class="prompt input_prompt">In&nbsp;[117]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="k">class</span> <span class="nc">SymbolJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
-    <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;F&#39;</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">infer</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
+</pre></div>
 
-    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">stack_effects</span> <span class="o">=</span> <span class="n">sec</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
+</div>
+</div>
+</div>
 
-<span class="k">class</span> <span class="nc">CombinatorJoyType</span><span class="p">(</span><span class="n">SymbolJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;C&#39;</span>
+<div class="output_wrapper">
+<div class="output">
 
-<span class="k">def</span> <span class="nf">dip_t</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">):</span>
-    <span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
-    <span class="n">expression</span> <span class="o">=</span> <span class="n">stack_concat</span><span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">expression</span><span class="p">))</span>
-    <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span>
 
-<span class="n">CONS</span> <span class="o">=</span> <span class="n">SymbolJoyType</span><span class="p">(</span><span class="s1">&#39;cons&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">cons</span><span class="p">],</span> <span class="mi">23</span><span class="p">)</span>
-<span class="n">DIP</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">&#39;dip&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">dip_t</span><span class="p">],</span> <span class="mi">44</span><span class="p">)</span>
+<div class="output_area">
 
+<div class="prompt output_prompt">Out[117]:</div>
 
-<span class="k">def</span> <span class="nf">kav</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
-    <span class="c1">#i, stack = F</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">return</span> <span class="p">[(</span><span class="n">F</span><span class="p">,</span> <span class="n">e</span><span class="p">)]</span>
-    <span class="n">n</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">e</span>
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">SymbolJoyType</span><span class="p">):</span>
-        <span class="n">Fs</span> <span class="o">=</span> <span class="p">[]</span>
-        <span class="k">for</span> <span class="n">sec</span> <span class="ow">in</span> <span class="n">n</span><span class="o">.</span><span class="n">stack_effects</span><span class="p">:</span>
-            <span class="n">Fs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">MC</span><span class="p">([</span><span class="n">F</span><span class="p">],</span> <span class="n">sec</span><span class="p">))</span>
-        <span class="k">return</span> <span class="p">[</span><span class="n">kav</span><span class="p">(</span><span class="n">Fn</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">Fn</span> <span class="ow">in</span> <span class="n">Fs</span><span class="p">]</span>
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">CombinatorJoyType</span><span class="p">):</span>
-        <span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
-        <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">n</span><span class="o">.</span><span class="n">stack_effects</span><span class="p">:</span>
-            <span class="n">s</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">e</span><span class="p">)</span>
-            <span class="n">new_F</span> <span class="o">=</span> <span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">s</span>
-            <span class="n">res</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">kav</span><span class="p">(</span><span class="n">new_F</span><span class="p">,</span> <span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="n">res</span>
-    <span class="n">lit</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
-    <span class="k">return</span> <span class="p">[</span><span class="n">kav</span><span class="p">(</span><span class="n">Fn</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">Fn</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">F</span><span class="p">],</span> <span class="p">[</span><span class="n">lit</span><span class="p">])]</span>
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>[(s1, (f1, s1)), (s1, (i1, s1))]</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In&nbsp;[118]:</div>
+<div class="inner_cell">
+    <div class="input_area">
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">infer</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
 </pre></div>
 
 </div>
 </div>
 </div>
 
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[118]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>[(s1, (f1, s1)), (s1, (i1, s1))]</pre>
 </div>
-<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+
 </div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In&nbsp;[119]:</div>
 <div class="inner_cell">
-<div class="text_cell_render border-box-sizing rendered_html">
-<p>compare, and be amazed:</p>
+    <div class="input_area">
+<div class=" highlight hl-ipython2"><pre><span></span><span class="k">for</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="n">infer</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
+    <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
+</pre></div>
+
+</div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
 
+
+<div class="output_area">
+
+<div class="prompt"></div>
+
+
+<div class="output_subarea output_stream output_stdout output_text">
+<pre>(-- f1)
+(-- i1)
+</pre>
 </div>
 </div>
+
+</div>
+</div>
+
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[117]:</div>
+<div class="prompt input_prompt">In&nbsp;[120]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">dip_t</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">):</span>
-    <span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
-    <span class="n">expression</span> <span class="o">=</span> <span class="n">stack_concat</span><span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">expression</span><span class="p">))</span>
-    <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">expression</span>
 </pre></div>
 
 </div>
 </div>
 </div>
 
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[120]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>(n1, (n2, (mul, ())))</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[118]:</div>
+<div class="prompt input_prompt">In&nbsp;[121]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">dip</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
-    <span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
-    <span class="n">expression</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
-    <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">infer</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
 </pre></div>
 
 </div>
 </div>
 </div>
 
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[121]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>[(s1, (f1, s1)), (s1, (i1, s1))]</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
 </div>
 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
 </div>
 <div class="inner_cell">
 <div class="text_cell_render border-box-sizing rendered_html">
-<p>And that brings us to current Work-In-Progress.  I'm pretty hopeful that the mixed-mode inferencer/interpreter <code>kav()</code> function along with the ability to specify multiple implementations for the combinators will permit modelling of the stack effects of e.g. <code>ifte</code>.  If I can keep up the pace I should be able to verify that conjecture by the end of June.</p>
+<p>And that brings us to current Work-In-Progress.  I'm pretty hopeful that the mixed-mode inferencer/interpreter <code>infer()</code> function along with the ability to specify multiple implementations for the combinators will permit modelling of the stack effects of e.g. <code>ifte</code>.  If I can keep up the pace I should be able to verify that conjecture by the end of June.</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div>
+<div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<h2 id="Conclusion">Conclusion<a class="anchor-link" href="#Conclusion">&#182;</a></h2><p>(for now...)</p>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div>
+<div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<p>Work remains to be done:</p>
+<ul>
+<li>the rest of the library has to be covered</li>
+<li>figure out how to deal with <code>loop</code> and <code>genrec</code>, etc..</li>
+<li>extend the types to check values (see the appendix)</li>
+<li>other kinds of "higher order" type variables, OR, AND, etc..</li>
+<li>maybe rewrite in Prolog for great good?</li>
+<li>definitions<ul>
+<li>don't permit composition of functions that don't compose</li>
+<li>auto-compile compilable functions</li>
+</ul>
+</li>
+<li>Compiling more than just the Yin functions.</li>
+<li>getting better visibility (than Python debugger.)</li>
+<li>DOOOOCS!!!!  Lots of docs!<ul>
+<li>docstrings all around</li>
+<li>improve this notebook (it kinda falls apart at the end narratively.  I went off and just started writing code to see if it would work.  It does, but now I have to come back and describe here what I did.</li>
+</ul>
+</li>
+</ul>
+
+</div>
+</div>
+</div>
+<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
+</div>
+<div class="inner_cell">
+<div class="text_cell_render border-box-sizing rendered_html">
+<p>I'm starting to realize that, with the inferencer/checker/compiler coming along, and with the UI ready to be rewritten in Joy, I'm close to a time when my ephasis is going to have to shift from crunchy code stuff to squishy human stuff.  I'm going to have to put normal people in front of this and see if, in fact, they <em>can</em> learn the basics of programming with it.</p>
 
 </div>
 </div>
@@ -16784,12 +16874,33 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[119]:</div>
+<div class="prompt input_prompt">In&nbsp;[122]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="nb">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="k">def</span> <span class="nf">_ge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+    <span class="k">return</span> <span class="p">(</span><span class="nb">issubclass</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
+            <span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;accept&#39;</span><span class="p">)</span>
+            <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">accept</span><span class="p">))</span>
+
+<span class="n">AnyJoyType</span><span class="o">.</span><span class="fm">__ge__</span> <span class="o">=</span> <span class="n">_ge</span>
+<span class="n">AnyJoyType</span><span class="o">.</span><span class="n">accept</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">long</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="nb">unicode</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">Symbol</span>
+<span class="n">StackJoyType</span><span class="o">.</span><span class="n">accept</span> <span class="o">=</span> <span class="nb">tuple</span>
+</pre></div>
 
-<span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
+</div>
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In&nbsp;[123]:</div>
+<div class="inner_cell">
+    <div class="input_area">
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">l2s</span><span class="p">((</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)))</span>
+
+<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">F</span><span class="p">:</span>
+    <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
 </pre></div>
 
 </div>
@@ -16805,94 +16916,9 @@ uncons = ([a1 .1.] -- a1 [.1.])
 <div class="prompt"></div>
 
 
-<div class="output_subarea output_text output_error">
-<pre>
-<span class="ansi-red-fg">---------------------------------------------------------------------------</span>
-<span class="ansi-red-fg">TypeError</span>                                 Traceback (most recent call last)
-<span class="ansi-green-fg">&lt;ipython-input-119-7fde90b4e88f&gt;</span> in <span class="ansi-cyan-fg">&lt;module&gt;</span><span class="ansi-blue-fg">()</span>
-<span class="ansi-green-intense-fg ansi-bold">      1</span> F <span class="ansi-blue-fg">=</span> reduce<span class="ansi-blue-fg">(</span>C<span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">(</span>pop<span class="ansi-blue-fg">,</span> swap<span class="ansi-blue-fg">,</span> rolldown<span class="ansi-blue-fg">,</span> rest<span class="ansi-blue-fg">,</span> rest<span class="ansi-blue-fg">,</span> cons<span class="ansi-blue-fg">,</span> cons<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">)</span>
-<span class="ansi-green-intense-fg ansi-bold">      2</span> 
-<span class="ansi-green-fg">----&gt; 3</span><span class="ansi-red-fg"> </span><span class="ansi-green-fg">print</span> doc_from_stack_effect<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">*</span>F<span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-98-ddee30dbb1a6&gt;</span> in <span class="ansi-cyan-fg">C</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">     10</span> <span class="ansi-green-fg">def</span> C<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     11</span>     f<span class="ansi-blue-fg">,</span> g <span class="ansi-blue-fg">=</span> relabel<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-fg">---&gt; 12</span><span class="ansi-red-fg">     </span><span class="ansi-green-fg">for</span> fg <span class="ansi-green-fg">in</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     13</span>         <span class="ansi-green-fg">yield</span> delabel<span class="ansi-blue-fg">(</span>fg<span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-97-5eb7ac5ad2c2&gt;</span> in <span class="ansi-cyan-fg">compose</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">      1</span> <span class="ansi-green-fg">def</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-fg">----&gt; 2</span><span class="ansi-red-fg">     </span><span class="ansi-blue-fg">(</span>f_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> g_out<span class="ansi-blue-fg">)</span> <span class="ansi-blue-fg">=</span> f<span class="ansi-blue-fg">,</span> g
-<span class="ansi-green-intense-fg ansi-bold">      3</span>     s <span class="ansi-blue-fg">=</span> unify<span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-intense-fg ansi-bold">      4</span>     <span class="ansi-green-fg">if</span> <span class="ansi-green-fg">not</span> s<span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">      5</span>         <span class="ansi-green-fg">raise</span> TypeError<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">&#39;Cannot unify %r and %r.&#39;</span> <span class="ansi-blue-fg">%</span> <span class="ansi-blue-fg">(</span>f_out<span class="ansi-blue-fg">,</span> g_in<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-98-ddee30dbb1a6&gt;</span> in <span class="ansi-cyan-fg">C</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">     10</span> <span class="ansi-green-fg">def</span> C<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     11</span>     f<span class="ansi-blue-fg">,</span> g <span class="ansi-blue-fg">=</span> relabel<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-fg">---&gt; 12</span><span class="ansi-red-fg">     </span><span class="ansi-green-fg">for</span> fg <span class="ansi-green-fg">in</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     13</span>         <span class="ansi-green-fg">yield</span> delabel<span class="ansi-blue-fg">(</span>fg<span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-97-5eb7ac5ad2c2&gt;</span> in <span class="ansi-cyan-fg">compose</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">      1</span> <span class="ansi-green-fg">def</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-fg">----&gt; 2</span><span class="ansi-red-fg">     </span><span class="ansi-blue-fg">(</span>f_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> g_out<span class="ansi-blue-fg">)</span> <span class="ansi-blue-fg">=</span> f<span class="ansi-blue-fg">,</span> g
-<span class="ansi-green-intense-fg ansi-bold">      3</span>     s <span class="ansi-blue-fg">=</span> unify<span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-intense-fg ansi-bold">      4</span>     <span class="ansi-green-fg">if</span> <span class="ansi-green-fg">not</span> s<span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">      5</span>         <span class="ansi-green-fg">raise</span> TypeError<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">&#39;Cannot unify %r and %r.&#39;</span> <span class="ansi-blue-fg">%</span> <span class="ansi-blue-fg">(</span>f_out<span class="ansi-blue-fg">,</span> g_in<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-98-ddee30dbb1a6&gt;</span> in <span class="ansi-cyan-fg">C</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">     10</span> <span class="ansi-green-fg">def</span> C<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     11</span>     f<span class="ansi-blue-fg">,</span> g <span class="ansi-blue-fg">=</span> relabel<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-fg">---&gt; 12</span><span class="ansi-red-fg">     </span><span class="ansi-green-fg">for</span> fg <span class="ansi-green-fg">in</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     13</span>         <span class="ansi-green-fg">yield</span> delabel<span class="ansi-blue-fg">(</span>fg<span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-97-5eb7ac5ad2c2&gt;</span> in <span class="ansi-cyan-fg">compose</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">      1</span> <span class="ansi-green-fg">def</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-fg">----&gt; 2</span><span class="ansi-red-fg">     </span><span class="ansi-blue-fg">(</span>f_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> g_out<span class="ansi-blue-fg">)</span> <span class="ansi-blue-fg">=</span> f<span class="ansi-blue-fg">,</span> g
-<span class="ansi-green-intense-fg ansi-bold">      3</span>     s <span class="ansi-blue-fg">=</span> unify<span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-intense-fg ansi-bold">      4</span>     <span class="ansi-green-fg">if</span> <span class="ansi-green-fg">not</span> s<span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">      5</span>         <span class="ansi-green-fg">raise</span> TypeError<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">&#39;Cannot unify %r and %r.&#39;</span> <span class="ansi-blue-fg">%</span> <span class="ansi-blue-fg">(</span>f_out<span class="ansi-blue-fg">,</span> g_in<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-98-ddee30dbb1a6&gt;</span> in <span class="ansi-cyan-fg">C</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">     10</span> <span class="ansi-green-fg">def</span> C<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     11</span>     f<span class="ansi-blue-fg">,</span> g <span class="ansi-blue-fg">=</span> relabel<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-fg">---&gt; 12</span><span class="ansi-red-fg">     </span><span class="ansi-green-fg">for</span> fg <span class="ansi-green-fg">in</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     13</span>         <span class="ansi-green-fg">yield</span> delabel<span class="ansi-blue-fg">(</span>fg<span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-97-5eb7ac5ad2c2&gt;</span> in <span class="ansi-cyan-fg">compose</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">      1</span> <span class="ansi-green-fg">def</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-fg">----&gt; 2</span><span class="ansi-red-fg">     </span><span class="ansi-blue-fg">(</span>f_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> g_out<span class="ansi-blue-fg">)</span> <span class="ansi-blue-fg">=</span> f<span class="ansi-blue-fg">,</span> g
-<span class="ansi-green-intense-fg ansi-bold">      3</span>     s <span class="ansi-blue-fg">=</span> unify<span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-intense-fg ansi-bold">      4</span>     <span class="ansi-green-fg">if</span> <span class="ansi-green-fg">not</span> s<span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">      5</span>         <span class="ansi-green-fg">raise</span> TypeError<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">&#39;Cannot unify %r and %r.&#39;</span> <span class="ansi-blue-fg">%</span> <span class="ansi-blue-fg">(</span>f_out<span class="ansi-blue-fg">,</span> g_in<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-98-ddee30dbb1a6&gt;</span> in <span class="ansi-cyan-fg">C</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">     10</span> <span class="ansi-green-fg">def</span> C<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     11</span>     f<span class="ansi-blue-fg">,</span> g <span class="ansi-blue-fg">=</span> relabel<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-fg">---&gt; 12</span><span class="ansi-red-fg">     </span><span class="ansi-green-fg">for</span> fg <span class="ansi-green-fg">in</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     13</span>         <span class="ansi-green-fg">yield</span> delabel<span class="ansi-blue-fg">(</span>fg<span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-97-5eb7ac5ad2c2&gt;</span> in <span class="ansi-cyan-fg">compose</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">      1</span> <span class="ansi-green-fg">def</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-fg">----&gt; 2</span><span class="ansi-red-fg">     </span><span class="ansi-blue-fg">(</span>f_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> g_out<span class="ansi-blue-fg">)</span> <span class="ansi-blue-fg">=</span> f<span class="ansi-blue-fg">,</span> g
-<span class="ansi-green-intense-fg ansi-bold">      3</span>     s <span class="ansi-blue-fg">=</span> unify<span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-intense-fg ansi-bold">      4</span>     <span class="ansi-green-fg">if</span> <span class="ansi-green-fg">not</span> s<span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">      5</span>         <span class="ansi-green-fg">raise</span> TypeError<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">&#39;Cannot unify %r and %r.&#39;</span> <span class="ansi-blue-fg">%</span> <span class="ansi-blue-fg">(</span>f_out<span class="ansi-blue-fg">,</span> g_in<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-98-ddee30dbb1a6&gt;</span> in <span class="ansi-cyan-fg">C</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">     10</span> <span class="ansi-green-fg">def</span> C<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     11</span>     f<span class="ansi-blue-fg">,</span> g <span class="ansi-blue-fg">=</span> relabel<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-fg">---&gt; 12</span><span class="ansi-red-fg">     </span><span class="ansi-green-fg">for</span> fg <span class="ansi-green-fg">in</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">     13</span>         <span class="ansi-green-fg">yield</span> delabel<span class="ansi-blue-fg">(</span>fg<span class="ansi-blue-fg">)</span>
-
-<span class="ansi-green-fg">&lt;ipython-input-97-5eb7ac5ad2c2&gt;</span> in <span class="ansi-cyan-fg">compose</span><span class="ansi-blue-fg">(f, g)</span>
-<span class="ansi-green-intense-fg ansi-bold">      1</span> <span class="ansi-green-fg">def</span> compose<span class="ansi-blue-fg">(</span>f<span class="ansi-blue-fg">,</span> g<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">:</span>
-<span class="ansi-green-fg">----&gt; 2</span><span class="ansi-red-fg">     </span><span class="ansi-blue-fg">(</span>f_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">,</span> <span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> g_out<span class="ansi-blue-fg">)</span> <span class="ansi-blue-fg">=</span> f<span class="ansi-blue-fg">,</span> g
-<span class="ansi-green-intense-fg ansi-bold">      3</span>     s <span class="ansi-blue-fg">=</span> unify<span class="ansi-blue-fg">(</span>g_in<span class="ansi-blue-fg">,</span> f_out<span class="ansi-blue-fg">)</span>
-<span class="ansi-green-intense-fg ansi-bold">      4</span>     <span class="ansi-green-fg">if</span> <span class="ansi-green-fg">not</span> s<span class="ansi-blue-fg">:</span>
-<span class="ansi-green-intense-fg ansi-bold">      5</span>         <span class="ansi-green-fg">raise</span> TypeError<span class="ansi-blue-fg">(</span><span class="ansi-blue-fg">&#39;Cannot unify %r and %r.&#39;</span> <span class="ansi-blue-fg">%</span> <span class="ansi-blue-fg">(</span>f_out<span class="ansi-blue-fg">,</span> g_in<span class="ansi-blue-fg">)</span><span class="ansi-blue-fg">)</span>
-
-<span class="ansi-red-fg">TypeError</span>: &#39;SymbolJoyType&#39; object is not iterable</pre>
+<div class="output_subarea output_stream output_stdout output_text">
+<pre>([a4 a5 .1.] a3 a2 a1 -- [a2 a3 .1.])
+</pre>
 </div>
 </div>
 
@@ -16902,7 +16928,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
+<div class="prompt input_prompt">In&nbsp;[124]:</div>
 <div class="inner_cell">
     <div class="input_area">
 <div class=" highlight hl-ipython2"><pre><span></span><span class="kn">from</span> <span class="nn">joy.parser</span> <span class="kn">import</span> <span class="n">text_to_expression</span>
@@ -16915,10 +16941,44 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
+<div class="prompt input_prompt">In&nbsp;[125]:</div>
+<div class="inner_cell">
+    <div class="input_area">
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">l2s</span><span class="p">((</span><span class="n">pop</span><span class="p">,</span> <span class="n">pop</span><span class="p">,</span> <span class="n">pop</span><span class="p">)))</span>
+
+<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">F</span><span class="p">:</span>
+    <span class="k">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
+</pre></div>
+
+</div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt"></div>
+
+
+<div class="output_subarea output_stream output_stdout output_text">
+<pre>(a3 a2 a1 --)
+</pre>
+</div>
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In&nbsp;[126]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;[3 4 ...] 2 1&#39;</span><span class="p">)</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;0 1 2&#39;</span><span class="p">)</span>
 <span class="n">s</span>
 </pre></div>
 
@@ -16926,13 +16986,66 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 </div>
 
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[126]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>(0, (1, (2, ())))</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
+<div class="prompt input_prompt">In&nbsp;[127]:</div>
+<div class="inner_cell">
+    <div class="input_area">
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
+</pre></div>
+
+</div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[127]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>(a1, (a2, (a3, s1)))</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In&nbsp;[128]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">s</span><span class="p">)</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
 <span class="n">L</span>
 </pre></div>
 
@@ -16940,23 +17053,165 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 </div>
 
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[128]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>()</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
+<div class="prompt input_prompt">In&nbsp;[129]:</div>
 <div class="inner_cell">
     <div class="input_area">
-<div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;0 1 2 [3 4]&#39;</span><span class="p">)</span>
+<span class="n">s</span>
 </pre></div>
 
 </div>
 </div>
 </div>
 
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[129]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>(0, (1, (2, ((3, (4, ())), ()))))</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
-<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
+<div class="prompt input_prompt">In&nbsp;[130]:</div>
+<div class="inner_cell">
+    <div class="input_area">
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
+</pre></div>
+
+</div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[130]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>(a1, (a2, (a3, s1)))</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In&nbsp;[131]:</div>
+<div class="inner_cell">
+    <div class="input_area">
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
+<span class="n">L</span>
+</pre></div>
+
+</div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[131]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>()</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In&nbsp;[132]:</div>
+<div class="inner_cell">
+    <div class="input_area">
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">s</span><span class="p">)</span>
+<span class="n">L</span>
+</pre></div>
+
+</div>
+</div>
+</div>
+
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt output_prompt">Out[132]:</div>
+
+
+
+
+<div class="output_text output_subarea output_execute_result">
+<pre>()</pre>
+</div>
+
+</div>
+
+</div>
+</div>
+
+</div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In&nbsp;[133]:</div>
 <div class="inner_cell">
     <div class="input_area">
 <div class=" highlight hl-ipython2"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
@@ -16966,6 +17221,29 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 </div>
 
+<div class="output_wrapper">
+<div class="output">
+
+
+<div class="output_area">
+
+<div class="prompt"></div>
+
+
+<div class="output_subarea output_text output_error">
+<pre>
+<span class="ansi-red-fg">---------------------------------------------------------------------------</span>
+<span class="ansi-red-fg">IndexError</span>                                Traceback (most recent call last)
+<span class="ansi-green-fg">&lt;ipython-input-133-58a8e44e9cba&gt;</span> in <span class="ansi-cyan-fg">&lt;module&gt;</span><span class="ansi-blue-fg">()</span>
+<span class="ansi-green-fg">----&gt; 1</span><span class="ansi-red-fg"> </span>F<span class="ansi-blue-fg">[</span><span class="ansi-cyan-fg">1</span><span class="ansi-blue-fg">]</span><span class="ansi-blue-fg">[</span><span class="ansi-cyan-fg">0</span><span class="ansi-blue-fg">]</span>
+
+<span class="ansi-red-fg">IndexError</span>: list index out of range</pre>
+</div>
+</div>
+
+</div>
+</div>
+
 </div>
 <div class="cell border-box-sizing code_cell rendered">
 <div class="input">
@@ -16980,6 +17258,19 @@ uncons = ([a1 .1.] -- a1 [.1.])
 </div>
 
 </div>
+<div class="cell border-box-sizing code_cell rendered">
+<div class="input">
+<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>
+<div class="inner_cell">
+    <div class="input_area">
+<div class=" highlight hl-ipython2"><pre><span></span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="mi">23</span>
+</pre></div>
+
+</div>
+</div>
+</div>
+
+</div>
 <div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">
 </div>
 <div class="inner_cell">
index 43b69e4..35e858f 100644 (file)
     "    if s is None:\n",
     "        s = {}\n",
     "\n",
-    "    if u == v:\n",
-    "        return s\n",
-    "\n",
     "    if isinstance(u, int):\n",
     "        s[u] = v\n",
-    "        return s\n",
-    "\n",
-    "    if isinstance(v, int):\n",
+    "    elif isinstance(v, int):\n",
     "        s[v] = u\n",
-    "        return s\n",
     "\n",
-    "    return False"
+    "    return s"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 20,
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Cannot unify (1, 2) and (1001, 1002).\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "try:\n",
     "    C(cons, uncons)\n",
     "        u = update(s, u)\n",
     "        v = update(s, v)\n",
     "\n",
-    "    if u == v:\n",
-    "        return s\n",
-    "\n",
     "    if isinstance(u, int):\n",
     "        s[u] = v\n",
-    "        return s\n",
     "\n",
-    "    if isinstance(v, int):\n",
+    "    elif isinstance(v, int):\n",
     "        s[v] = u\n",
-    "        return s\n",
     "\n",
-    "    if isinstance(u, tuple) and isinstance(v, tuple):\n",
-    "        if len(u) != len(v) != 2:\n",
-    "            raise ValueError(repr((u, v)))\n",
-    "        for uu, vv in zip(u, v):\n",
-    "            s = unify(uu, vv, s)\n",
-    "            if s == False: # (instead of a substitution dict.)\n",
-    "                break\n",
-    "        return s\n",
-    " \n",
-    "    return False"
+    "    elif isinstance(u, tuple) and isinstance(v, tuple):\n",
+    "\n",
+    "        if len(u) != 2 or len(v) != 2:\n",
+    "            # Not a type error, caller passed in a bad value.\n",
+    "            raise ValueError(repr((u, v)))  # FIXME this message sucks.\n",
+    "\n",
+    "        (a, b), (c, d) = u, v\n",
+    "        s = unify(a, c, s)\n",
+    "        if s != False:\n",
+    "            s = unify(b, d, s)\n",
+    "\n",
+    "    return s"
    ]
   },
   {
    "metadata": {},
    "source": [
     "#### `compose()` version 2\n",
-    "This function has to be modified to use the new datastructures and it is no longer recursive, instead recursion happens as part of unification.  Further, the first and second of Pöial's rules are now handled automatically by the unification algorithm."
+    "This function has to be modified to use the new datastructures and it is no longer recursive, instead recursion happens as part of unification.  Further, the first and second of Pöial's rules are now handled automatically by the unification algorithm.  (One easy way to see this is that now an empty stack effect comment is represented by a `StackJoyType` instance which is not \"falsey\" and so neither of the first two rules' `if` clauses will ever be `True`.  Later on I change the \"truthiness\" of `StackJoyType` to false to let e.g. `joy.utils.stack.concat` work with our stack effect comment cons-list tuples.)"
    ]
   },
   {
     }
    ],
    "source": [
-    "C(C(stack, uncons), uncons)"
+    "reduce(C, (stack, uncons, uncons))"
    ]
   },
   {
    "source": [
     "print ; print doc_from_stack_effect(*stack)\n",
     "print ; print doc_from_stack_effect(*C(stack, uncons))\n",
-    "print ; print doc_from_stack_effect(*C(C(stack, uncons), uncons))\n",
-    "print ; print doc_from_stack_effect(*C(C(stack, uncons), cons))"
+    "print ; print doc_from_stack_effect(*reduce(C, (stack, uncons, uncons)))\n",
+    "print ; print doc_from_stack_effect(*reduce(C, (stack, uncons, cons)))"
    ]
   },
   {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "(f1 -- f2)\n",
-      "(i1 -- i2)\n"
+      "(n1 -- n2)\n"
      ]
     }
    ],
    "source": [
-    "for f in MC([dup], muls):\n",
+    "for f in MC([dup], [mul]):\n",
     "    print doc_from_stack_effect(*f)"
    ]
   },
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "(n1 -- n2)\n"
+      "(f1 -- f2)\n",
+      "(i1 -- i2)\n"
      ]
     }
    ],
    "source": [
-    "for f in MC([dup], [mul]):\n",
+    "for f in MC([dup], muls):\n",
     "    print doc_from_stack_effect(*f)"
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
    "execution_count": 103,
    "metadata": {},
    "outputs": [
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
     "## Part VII: Typing Combinators\n",
     "\n",
-    "In order to compute the stack effect of combinators you kinda have to have the quoted programs they expect available.  In the most general case, the `i` combinator, you can't say anything about it's stack effect other than it expects one quote:\n",
+    "In order to compute the stack effect of combinators you kinda have to have the quoted programs they expect available.  In the most general case, the `i` combinator, you can't say anything about its stack effect other than it expects one quote:\n",
     "\n",
     "    i (... [.1.] -- ... .1.)\n",
     "\n",
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
+    "### Hybrid Inferencer/Interpreter\n",
     "I think there's a way forward.  If we convert our list of terms we are composing into a stack structure we can use it as a *Joy expression*, then we can treat the *output half* of a function's stack effect comment as a Joy interpreter stack, and just execute combinators directly.  We can hybridize the compostition function with an interpreter to evaluate combinators, compose non-combinator functions, and put type variables on the stack.  For combinators like `branch` that can have more than one stack effect we have to \"split universes\" again and return both."
    ]
   },
     "class SymbolJoyType(FunctionJoyType): prefix = 'F'\n",
     "class CombinatorJoyType(FunctionJoyType): prefix = 'C'\n",
     "\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 108,
-   "metadata": {},
-   "outputs": [],
-   "source": [
+    "\n",
     "def flatten(g):\n",
     "    return list(chain.from_iterable(g))\n",
     "\n",
   },
   {
    "cell_type": "code",
-   "execution_count": 109,
+   "execution_count": 108,
    "metadata": {},
    "outputs": [],
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": 110,
+   "execution_count": 109,
    "metadata": {},
    "outputs": [],
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": 111,
+   "execution_count": 110,
    "metadata": {},
    "outputs": [],
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": 112,
+   "execution_count": 111,
    "metadata": {},
    "outputs": [],
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": 113,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "expression = l2s([n1, n2, (mul, s2), (stack, s3), dip, infra, first])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 114,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "(n1, (n2, ((mul, s2), ((stack, s3), (dip, (infra, (first, ())))))))"
-      ]
-     },
-     "execution_count": 114,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "expression"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 115,
+   "execution_count": 112,
    "metadata": {},
    "outputs": [],
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": 116,
+   "execution_count": 113,
    "metadata": {},
    "outputs": [
     {
        "(n1, (n2, (mul, ())))"
       ]
      },
-     "execution_count": 116,
+     "execution_count": 113,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 117,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "[(s1, (f1, s1)), (s1, (i1, s1))]"
-      ]
-     },
-     "execution_count": 117,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "infer(expression)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 118,
+   "execution_count": 114,
    "metadata": {},
    "outputs": [
     {
        "[(s1, (f1, s1)), (s1, (i1, s1))]"
       ]
      },
-     "execution_count": 118,
+     "execution_count": 114,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 119,
+   "execution_count": 115,
    "metadata": {},
    "outputs": [
     {
    ]
   },
   {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "`nullary`, broken here but the current code handles it.  I have to \"backport\" the work I'm doing to this notebook.  I've run ahead of myself."
+   ]
+  },
+  {
    "cell_type": "code",
-   "execution_count": 120,
+   "execution_count": 116,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "expression = l2s([n1, n2, (mul, s2), (stack, s3), dip, infra, first])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 117,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "(n1, (n2, (mul, ())))"
+       "(n1, (n2, ((mul, s2), ((stack, s3), (dip, (infra, (first, ())))))))"
       ]
      },
-     "execution_count": 120,
+     "execution_count": 117,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 121,
+   "execution_count": 132,
    "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "[(s1, (f1, s1)), (s1, (i1, s1))]"
+       "[]"
       ]
      },
-     "execution_count": 121,
+     "execution_count": 132,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "infer(expression)"
+    "infer(expression)  # should be three numbers."
    ]
   },
   {
-   "cell_type": "markdown",
+   "cell_type": "code",
+   "execution_count": 119,
    "metadata": {},
+   "outputs": [],
    "source": [
-    "And that brings us to current Work-In-Progress.  I'm pretty hopeful that the mixed-mode inferencer/interpreter `infer()` function along with the ability to specify multiple implementations for the combinators will permit modelling of the stack effects of e.g. `ifte`.  If I can keep up the pace I should be able to verify that conjecture by the end of June."
+    "for stack_effect_comment in infer(expression):\n",
+    "    print doc_from_stack_effect(*stack_effect_comment)"
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
+   "cell_type": "markdown",
    "metadata": {},
-   "outputs": [],
-   "source": []
+   "source": [
+    "And that brings us to current Work-In-Progress.  I'm pretty hopeful that the mixed-mode inferencer/interpreter `infer()` function along with the ability to specify multiple implementations for the combinators will permit modelling of the stack effects of e.g. `ifte`."
+   ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
+   "cell_type": "markdown",
    "metadata": {},
-   "outputs": [],
-   "source": []
+   "source": [
+    "## Conclusion\n",
+    "(for now...)"
+   ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
+   "cell_type": "markdown",
    "metadata": {},
-   "outputs": [],
-   "source": []
+   "source": [
+    "Work remains to be done:\n",
+    "\n",
+    "- the rest of the library has to be covered\n",
+    "- figure out how to deal with `loop` and `genrec`, etc..\n",
+    "- extend the types to check values (see the appendix)\n",
+    "- other kinds of \"higher order\" type variables, OR, AND, etc..\n",
+    "- maybe rewrite in Prolog for great good?\n",
+    "- definitions\n",
+    "  - don't permit composition of functions that don't compose\n",
+    "  - auto-compile compilable functions\n",
+    "- Compiling more than just the Yin functions.\n",
+    "- getting better visibility (than Python debugger.)\n",
+    "- DOOOOCS!!!!  Lots of docs!\n",
+    "  - docstrings all around\n",
+    "  - improve this notebook (it kinda falls apart at the end narratively.  I went off and just started writing code to see if it would work.  It does, but now I have to come back and describe here what I did."
+   ]
   },
   {
-   "cell_type": "code",
-   "execution_count": null,
+   "cell_type": "markdown",
    "metadata": {},
-   "outputs": [],
-   "source": []
+   "source": [
+    "I'm starting to realize that, with the inferencer/checker/compiler coming along, and with the UI ready to be rewritten in Joy, I'm close to a time when my ephasis is going to have to shift from crunchy code stuff to squishy human stuff.  I'm going to have to put normal people in front of this and see if, in fact, they *can* learn the basics of programming with it."
+   ]
   },
   {
    "cell_type": "code",
   },
   {
    "cell_type": "code",
-   "execution_count": 122,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
-   "source": [
-    "hasattr?"
-   ]
+   "source": []
   },
   {
    "cell_type": "markdown",
   },
   {
    "cell_type": "code",
-   "execution_count": 123,
+   "execution_count": 120,
    "metadata": {},
    "outputs": [],
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": 124,
+   "execution_count": 121,
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
-   "execution_count": 125,
+   "execution_count": 122,
    "metadata": {},
    "outputs": [],
    "source": [
   },
   {
    "cell_type": "code",
-   "execution_count": 126,
+   "execution_count": 123,
    "metadata": {},
    "outputs": [
     {
   },
   {
    "cell_type": "code",
-   "execution_count": 127,
+   "execution_count": 124,
    "metadata": {},
    "outputs": [
     {
        "(0, (1, (2, ())))"
       ]
      },
-     "execution_count": 127,
+     "execution_count": 124,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 128,
+   "execution_count": 125,
    "metadata": {},
    "outputs": [
     {
        "(a1, (a2, (a3, s1)))"
       ]
      },
-     "execution_count": 128,
+     "execution_count": 125,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 129,
+   "execution_count": 126,
    "metadata": {},
    "outputs": [
     {
        "()"
       ]
      },
-     "execution_count": 129,
+     "execution_count": 126,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 130,
+   "execution_count": 127,
    "metadata": {},
    "outputs": [
     {
        "(0, (1, (2, ((3, (4, ())), ()))))"
       ]
      },
-     "execution_count": 130,
+     "execution_count": 127,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 131,
+   "execution_count": 128,
    "metadata": {},
    "outputs": [
     {
        "(a1, (a2, (a3, s1)))"
       ]
      },
-     "execution_count": 131,
+     "execution_count": 128,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 132,
+   "execution_count": 129,
    "metadata": {},
    "outputs": [
     {
        "()"
       ]
      },
-     "execution_count": 132,
+     "execution_count": 129,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 133,
+   "execution_count": 130,
    "metadata": {},
    "outputs": [
     {
        "()"
       ]
      },
-     "execution_count": 133,
+     "execution_count": 130,
      "metadata": {},
      "output_type": "execute_result"
     }
   },
   {
    "cell_type": "code",
-   "execution_count": 134,
+   "execution_count": 131,
    "metadata": {},
    "outputs": [
     {
      "traceback": [
       "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
       "\u001b[0;31mIndexError\u001b[0m                                Traceback (most recent call last)",
-      "\u001b[0;32m<ipython-input-134-58a8e44e9cba>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mF\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+      "\u001b[0;32m<ipython-input-131-58a8e44e9cba>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mF\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
       "\u001b[0;31mIndexError\u001b[0m: list index out of range"
      ]
     }
    "source": [
     "concat(a, b)"
    ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "class SymbolJoyType(AnyJoyType):\n",
-    "    prefix = 'F'\n",
-    "\n",
-    "    def __init__(self, name, sec, number):\n",
-    "        self.name = name\n",
-    "        self.stack_effects = sec\n",
-    "        self.number = number\n",
-    "\n",
-    "class CombinatorJoyType(SymbolJoyType): prefix = 'C'\n",
-    "\n",
-    "def dip_t(stack, expression):\n",
-    "    (quote, (a1, stack)) = stack\n",
-    "    expression = stack_concat(quote, (a1, expression))\n",
-    "    return stack, expression\n",
-    "\n",
-    "CONS = SymbolJoyType('cons', [cons], 23)\n",
-    "DIP = CombinatorJoyType('dip', [dip_t], 44)\n",
-    "\n",
-    "\n",
-    "def kav(F, e):\n",
-    "    #i, stack = F\n",
-    "    if not e:\n",
-    "        return [(F, e)]\n",
-    "    n, e = e\n",
-    "    if isinstance(n, SymbolJoyType):\n",
-    "        Fs = []\n",
-    "        for sec in n.stack_effects:\n",
-    "            Fs.extend(MC([F], sec))\n",
-    "        return [kav(Fn, e) for Fn in Fs]\n",
-    "    if isinstance(n, CombinatorJoyType):\n",
-    "        res = []\n",
-    "        for f in n.stack_effects:\n",
-    "            s, e = f(F[1], e)\n",
-    "            new_F = F[0], s\n",
-    "            res.extend(kav(new_F, e))\n",
-    "        return res\n",
-    "    lit = S[0], (n, S[0])\n",
-    "    return [kav(Fn, e) for Fn in MC([F], [lit])]\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "compare, and be amazed:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "def dip_t(stack, expression):\n",
-    "    (quote, (a1, stack)) = stack\n",
-    "    expression = stack_concat(quote, (a1, expression))\n",
-    "    return stack, expression"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "def dip(stack, expression, dictionary):\n",
-    "    (quote, (x, stack)) = stack\n",
-    "    expression = (x, expression)\n",
-    "    return stack, concat(quote, expression), dictionary"
-   ]
   }
  ],
  "metadata": {
index 0261bbe..9a723c0 100644 (file)
@@ -1,15 +1,11 @@
 
 # Type Inference
 
-This notebook presents a simple type inferencer for Joy code.  It can infer the stack effect of most Joy expressions.  It built largely by means of existing ideas and research (some of it may be original but I'm not able to say, as I don't fully understand the all of the source material in the depth required to make that call.)  A great overview of the existing knowledge is a talk ["Type Inference in Stack-Based Programming Languages"](http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/) given by Rob Kleffner on or about 2017-03-10 as part of a course on the history of programming languages.
+This notebook presents a simple type inferencer for Joy code.  It can infer the stack effect of most Joy expressions.  It's built largely by means of existing ideas and research.  (A great overview of the existing knowledge is a talk ["Type Inference in Stack-Based Programming Languages"](http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/) given by Rob Kleffner on or about 2017-03-10 as part of a course on the history of programming languages.)
 
-The notebook starts with a simple inferencer based on the work of Jaanus Pöial which we then progressively elaborate to cover more Joy semantics.  Along the way we write a simple "compiler" that emits Python code for what I like to call Yin functions.
+The notebook starts with a simple inferencer based on the work of Jaanus Pöial which we then progressively elaborate to cover more Joy semantics.  Along the way we write a simple "compiler" that emits Python code for what I like to call Yin functions.  (Yin functions are those that only rearrange values in stacks, as opposed to Yang functions that actually work on the values themselves.)
 
-Yin functions are those that only rearrange values in stacks, as opposed to Yang functions that actually work on the values themselves.  It's interesting to note that a Joy with *only* stacks (no other kinds of values) can be made and is Turing-complete, therefore all Yang functions are actually Yin functions, and all computation can be performed by manipulations of structures of containers, which is a restatement of the Laws of Form.  (Also, this implies that every program can be put into a form such that it can be computed in a single step, although that step may be enormous or unending.)
 
-Although I haven't completed it yet, a Joy based on Laws of Form provides the foundation for a provably correct computing system "down to the metal".  This is my original and still primary motivation for developing Joy.  (I want a proven-correct Operating System for a swarm of trash-collecting recycler robots.  To trust it I have to implementment it myself from first principles, and I'm not smart enough to truly grok the existing literature and software, so I had to go look for and find LoF and Joy.  Now that I have the mental tools to build my robot OS I can get down to it.
-
-Anyhow, here's type inference...
 
 ## Part I: Pöial's Rules
 
@@ -147,7 +143,7 @@ def poswrd(stack):
 
 This eliminates the internal work of the first version.  Because this function only rearranges the stack and doesn't do any actual processing on the stack items themselves all the information needed to implement it is in the stack effect comment.
 
-### Functions on Lists
+### Functions on Stacks
 These are slightly tricky.
 
     rest ( [1 ...] -- [...] )
@@ -345,18 +341,12 @@ def unify(u, v, s=None):
     if s is None:
         s = {}
 
-    if u == v:
-        return s
-
     if isinstance(u, int):
         s[u] = v
-        return s
-
-    if isinstance(v, int):
+    elif isinstance(v, int):
         s[v] = u
-        return s
 
-    return False
+    return s
 ```
 
 ### `update()`
@@ -566,9 +556,6 @@ except Exception, e:
     print e
 ```
 
-    Cannot unify (1, 2) and (1001, 1002).
-
-
 #### `unify()` version 2
 The problem is that the `unify()` function as written doesn't handle the case when both terms are tuples.  We just have to add a clause to deal with this recursively:
 
@@ -581,27 +568,24 @@ def unify(u, v, s=None):
         u = update(s, u)
         v = update(s, v)
 
-    if u == v:
-        return s
-
     if isinstance(u, int):
         s[u] = v
-        return s
 
-    if isinstance(v, int):
+    elif isinstance(v, int):
         s[v] = u
-        return s
 
-    if isinstance(u, tuple) and isinstance(v, tuple):
-        if len(u) != len(v) != 2:
-            raise ValueError(repr((u, v)))
-        for uu, vv in zip(u, v):
-            s = unify(uu, vv, s)
-            if s == False: # (instead of a substitution dict.)
-                break
-        return s
-    return False
+    elif isinstance(u, tuple) and isinstance(v, tuple):
+
+        if len(u) != 2 or len(v) != 2:
+            # Not a type error, caller passed in a bad value.
+            raise ValueError(repr((u, v)))  # FIXME this message sucks.
+
+        (a, b), (c, d) = u, v
+        s = unify(a, c, s)
+        if s != False:
+            s = unify(b, d, s)
+
+    return s
 ```
 
 
@@ -1142,7 +1126,7 @@ def delabel(f, seen=None, c=None):
         pass
 
     if not isinstance(f, tuple):
-        seen[f] = f.__class__(c[f.prefix])
+        seen[f] = f.__class__(c[f.prefix] + 1)
         c[f.prefix] += 1
         return seen[f]
 
@@ -1157,7 +1141,7 @@ delabel(foo)
 
 
 
-    (((a0,), (a0, a0)), ((n0, n1), (n2,)))
+    (((a1,), (a1, a1)), ((n1, n2), (n3,)))
 
 
 
@@ -1280,7 +1264,7 @@ for name, stack_effect_comment in sorted(DEFS.items()):
     print name, '=', doc_from_stack_effect(*stack_effect_comment)
 ```
 
-    ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+    ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
     cons = (a1 [.1.] -- [a1 .1.])
     divmod_ = (n2 n1 -- n4 n3)
     dup = (a1 -- a1 a1)
@@ -1297,13 +1281,13 @@ for name, stack_effect_comment in sorted(DEFS.items()):
     rest = ([a1 .1.] -- [.1.])
     rolldown = (a1 a2 a3 -- a2 a3 a1)
     rollup = (a1 a2 a3 -- a3 a1 a2)
-    rrest = ([a0 a1 .0.] -- [.0.])
-    second = ([a0 a1 .0.] -- a1)
-    sqrt = (n0 -- n1)
+    rrest = ([a1 a2 .1.] -- [.1.])
+    second = ([a1 a2 .1.] -- a2)
+    sqrt = (n1 -- n2)
     succ = (n1 -- n2)
     swap = (a1 a2 -- a2 a1)
-    swons = ([.0.] a0 -- [a0 .0.])
-    third = ([a0 a1 a2 .0.] -- a2)
+    swons = ([.1.] a1 -- [a1 .1.])
+    third = ([a1 a2 a3 .1.] -- a3)
     tuck = (a2 a1 -- a1 a2 a1)
     uncons = ([a1 .1.] -- a1 [.1.])
 
@@ -1323,7 +1307,7 @@ C(dup, mul)
 
 
 
-    ((n0,), (n1,))
+    ((n1,), (n2,))
 
 
 
@@ -1338,7 +1322,7 @@ F
 
 
 
-    (((a0, (a1, s0)), a2, a3, a4), ((a3, (a2, s0)),))
+    (((a1, (a2, s1)), a3, a4, a5), ((a4, (a3, s1)),))
 
 
 
@@ -1347,7 +1331,7 @@ F
 print doc_from_stack_effect(*F)
 ```
 
-    ([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])
+    ([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])
 
 
 Some otherwise inefficient functions are no longer to be feared.  We can also get the effect of combinators in some limited cases.
@@ -1364,7 +1348,7 @@ def neato(*funcs):
 neato(rollup, swap, rolldown)
 ```
 
-    (a0 a1 a2 -- a1 a0 a2)
+    (a1 a2 a3 -- a2 a1 a3)
 
 
 
@@ -1373,7 +1357,7 @@ neato(rollup, swap, rolldown)
 neato(popdd, rolldown, pop)
 ```
 
-    (a0 a1 a2 a3 -- a2 a3)
+    (a1 a2 a3 a4 -- a3 a4)
 
 
 
@@ -1382,7 +1366,7 @@ neato(popdd, rolldown, pop)
 neato(rollup, swap)
 ```
 
-    (a0 a1 a2 -- a2 a1 a0)
+    (a1 a2 a3 -- a3 a2 a1)
 
 
 #### `compile_()` version 2
@@ -1411,9 +1395,9 @@ print compile_('F', F)
 ```
 
     def F(stack):
-        """([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])"""
-        (a4, (a3, (a2, ((a0, (a1, s0)), stack)))) = stack
-        return ((a3, (a2, s0)), stack)
+        """([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])"""
+        (a5, (a4, (a3, ((a1, (a2, s1)), stack)))) = stack
+        return ((a4, (a3, s1)), stack)
 
 
 But it cannot magically create new functions that involve e.g. math and such.  Note that this is *not* a `sqr` function implementation:
@@ -1424,9 +1408,9 @@ print compile_('sqr', C(dup, mul))
 ```
 
     def sqr(stack):
-        """(n0 -- n1)"""
-        (n0, stack) = stack
-        return (n1, stack)
+        """(n1 -- n2)"""
+        (n1, stack) = stack
+        return (n2, stack)
 
 
 (Eventually I should come back around to this becuase it's not tooo difficult to exend this code to be able to compile e.g. `n3 = mul(n1, n2)` for `mul` and insert it in the right place with the right variable names.  It requires a little more support from the library functions, in that we need to know to call `mul()` the Python function for `mul` the Joy function, but since *most* of the math functions (at least) are already wrappers it should be straightforward.)
@@ -1450,7 +1434,7 @@ for name, stack_effect_comment in sorted(defs().items()):
         print name, '=', doc_from_stack_effect(*stack_effect_comment)
 ```
 
-    ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+    ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
     cons = (a1 [.1.] -- [a1 .1.])
     dup = (a1 -- a1 a1)
     dupd = (a2 a1 -- a2 a2 a1)
@@ -1463,11 +1447,11 @@ for name, stack_effect_comment in sorted(defs().items()):
     rest = ([a1 .1.] -- [.1.])
     rolldown = (a1 a2 a3 -- a2 a3 a1)
     rollup = (a1 a2 a3 -- a3 a1 a2)
-    rrest = ([a0 a1 .0.] -- [.0.])
-    second = ([a0 a1 .0.] -- a1)
+    rrest = ([a1 a2 .1.] -- [.1.])
+    second = ([a1 a2 .1.] -- a2)
     swap = (a1 a2 -- a2 a1)
-    swons = ([.0.] a0 -- [a0 .0.])
-    third = ([a0 a1 a2 .0.] -- a2)
+    swons = ([.1.] a1 -- [a1 .1.])
+    third = ([a1 a2 a3 .1.] -- a3)
     tuck = (a2 a1 -- a1 a2 a1)
     uncons = ([a1 .1.] -- a1 [.1.])
 
@@ -1530,7 +1514,7 @@ Let's try `stack∘uncons∘uncons`:
 It works.
 
 #### `compose()` version 2
-This function has to be modified to use the new datastructures and it is no longer recursive, instead recursion happens as part of unification.  Further, the first and second of Pöial's rules are now handled automatically by the unification algorithm.
+This function has to be modified to use the new datastructures and it is no longer recursive, instead recursion happens as part of unification.  Further, the first and second of Pöial's rules are now handled automatically by the unification algorithm.  (One easy way to see this is that now an empty stack effect comment is represented by a `StackJoyType` instance which is not "falsey" and so neither of the first two rules' `if` clauses will ever be `True`.  Later on I change the "truthiness" of `StackJoyType` to false to let e.g. `joy.utils.stack.concat` work with our stack effect comment cons-list tuples.)
 
 
 ```python
@@ -1567,19 +1551,19 @@ C(stack, uncons)
 
 
 
-    ((a0, s0), (s0, (a0, (a0, s0))))
+    ((a1, s1), (s1, (a1, (a1, s1))))
 
 
 
 
 ```python
-C(C(stack, uncons), uncons)
+reduce(C, (stack, uncons, uncons))
 ```
 
 
 
 
-    ((a0, (a1, s0)), (s0, (a1, (a0, (a0, (a1, s0))))))
+    ((a1, (a2, s1)), (s1, (a2, (a1, (a1, (a2, s1))))))
 
 
 
@@ -1643,7 +1627,7 @@ for name, stack_effect_comment in sorted(NEW_DEFS.items()):
     print name, '=', doc_from_stack_effect(*stack_effect_comment)
 ```
 
-    ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+    ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
     cons = (a1 [.1.] -- [a1 .1.])
     divmod_ = (n2 n1 -- n4 n3)
     dup = (a1 -- a1 a1)
@@ -1660,15 +1644,15 @@ for name, stack_effect_comment in sorted(NEW_DEFS.items()):
     rest = ([a1 .1.] -- [.1.])
     rolldown = (a1 a2 a3 -- a2 a3 a1)
     rollup = (a1 a2 a3 -- a3 a1 a2)
-    rrest = ([a0 a1 .0.] -- [.0.])
-    second = ([a0 a1 .0.] -- a1)
-    sqrt = (n0 -- n1)
+    rrest = ([a1 a2 .1.] -- [.1.])
+    second = ([a1 a2 .1.] -- a2)
+    sqrt = (n1 -- n2)
     stack = (... -- ... [...])
     succ = (n1 -- n2)
     swaack = ([.1.] -- [.0.])
     swap = (a1 a2 -- a2 a1)
-    swons = ([.0.] a0 -- [a0 .0.])
-    third = ([a0 a1 a2 .0.] -- a2)
+    swons = ([.1.] a1 -- [a1 .1.])
+    third = ([a1 a2 a3 .1.] -- a3)
     tuck = (a2 a1 -- a1 a2 a1)
     uncons = ([a1 .1.] -- a1 [.1.])
 
@@ -1677,18 +1661,18 @@ for name, stack_effect_comment in sorted(NEW_DEFS.items()):
 ```python
 print ; print doc_from_stack_effect(*stack)
 print ; print doc_from_stack_effect(*C(stack, uncons))
-print ; print doc_from_stack_effect(*C(C(stack, uncons), uncons))
-print ; print doc_from_stack_effect(*C(C(stack, uncons), cons))
+print ; print doc_from_stack_effect(*reduce(C, (stack, uncons, uncons)))
+print ; print doc_from_stack_effect(*reduce(C, (stack, uncons, cons)))
 ```
 
     
     (... -- ... [...])
     
-    (... a0 -- ... a0 a0 [...])
+    (... a1 -- ... a1 a1 [...])
     
-    (... a1 a0 -- ... a1 a0 a0 a1 [...])
+    (... a2 a1 -- ... a2 a1 a1 a2 [...])
     
-    (... a0 -- ... a0 [a0 ...])
+    (... a1 -- ... a1 [a1 ...])
 
 
 
@@ -1696,7 +1680,7 @@ print ; print doc_from_stack_effect(*C(C(stack, uncons), cons))
 print doc_from_stack_effect(*C(ccons, stack))
 ```
 
-    (... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])
+    (... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])
 
 
 
@@ -1709,7 +1693,7 @@ Q
 
 
 
-    ((s0, (a0, (a1, s1))), (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1)))
+    ((s1, (a1, (a2, s2))), (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2)))
 
 
 
@@ -1734,9 +1718,9 @@ print compile_('Q', Q)
 ```
 
     def Q(stack):
-        """(... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])"""
-        (s0, (a0, (a1, s1))) = stack
-        return (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1))
+        """(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])"""
+        (s1, (a1, (a2, s2))) = stack
+        return (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2))
 
 
 
@@ -1766,7 +1750,7 @@ print doc_from_stack_effect(*enstacken)
 print doc_from_stack_effect(*C(cons, unstack))
 ```
 
-    (a0 [.0.] -- a0)
+    (a1 [.1.] -- a1)
 
 
 
@@ -1774,7 +1758,7 @@ print doc_from_stack_effect(*C(cons, unstack))
 print doc_from_stack_effect(*C(cons, enstacken))
 ```
 
-    (a0 [.0.] -- [[a0 .0.] .1.])
+    (a1 [.1.] -- [[a1 .1.] .2.])
 
 
 
@@ -1785,7 +1769,7 @@ C(cons, unstack)
 
 
 
-    ((s0, (a0, s1)), (a0, s0))
+    ((s1, (a1, s2)), (a1, s1))
 
 
 
@@ -1833,8 +1817,8 @@ for f in muls:
     print doc_from_stack_effect(*dup), doc_from_stack_effect(*f), doc_from_stack_effect(*e)
 ```
 
-    (a1 -- a1 a1) (i1 i2 -- i3) (i0 -- i1)
-    (a1 -- a1 a1) (f1 f2 -- f3) (f0 -- f1)
+    (a1 -- a1 a1) (i1 i2 -- i3) (i1 -- i2)
+    (a1 -- a1 a1) (f1 f2 -- f3) (f1 -- f2)
 
 
 
@@ -1856,21 +1840,21 @@ def MC(F, G):
 
 
 ```python
-for f in MC([dup], muls):
+for f in MC([dup], [mul]):
     print doc_from_stack_effect(*f)
 ```
 
-    (f0 -- f1)
-    (i0 -- i1)
+    (n1 -- n2)
 
 
 
 ```python
-for f in MC([dup], [mul]):
+for f in MC([dup], muls):
     print doc_from_stack_effect(*f)
 ```
 
-    (n0 -- n1)
+    (f1 -- f2)
+    (i1 -- i2)
 
 
 ### Representing an Unbounded Sequence of Types
@@ -2155,8 +2139,8 @@ for f in MC([dup], muls):
     print doc_from_stack_effect(*f)
 ```
 
-    (f0 -- f1)
-    (i0 -- i1)
+    (f1 -- f2)
+    (i1 -- i2)
 
 
 
@@ -2167,7 +2151,7 @@ for f in MC([dup], [sum_]):
     print doc_from_stack_effect(*f)
 ```
 
-    ([n0* .0.] -- [n0* .0.] n0)
+    ([n1* .1.] -- [n1* .1.] n1)
 
 
 
@@ -2178,8 +2162,8 @@ for f in MC([cons], [sum_]):
     print doc_from_stack_effect(*f)
 ```
 
-    (a0 [.0.] -- n0)
-    (n0 [n0* .0.] -- n1)
+    (a1 [.1.] -- n1)
+    (n1 [n1* .1.] -- n2)
 
 
 
@@ -2192,7 +2176,7 @@ for f in MC([cons], [sum_]):
     print doc_from_stack_effect(*f)
 ```
 
-    (a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n0 [n0* .0.] -- n1)
+    (a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n1 [n1* .1.] -- n2)
 
 
 
@@ -2416,78 +2400,96 @@ expression = l2s([n1, n2, mul])
 
 
 ```python
+expression
+```
+
+
+
+
+    (n1, (n2, (mul, ())))
+
+
+
+
+```python
 infer(expression)
 ```
 
 
 
 
-    []
+    [(s1, (f1, s1)), (s1, (i1, s1))]
 
 
 
 
 ```python
-class SymbolJoyType(AnyJoyType):
-    prefix = 'F'
+infer(expression)
+```
 
-    def __init__(self, name, sec, number):
-        self.name = name
-        self.stack_effects = sec
-        self.number = number
 
-class CombinatorJoyType(SymbolJoyType): prefix = 'C'
 
-def dip_t(stack, expression):
-    (quote, (a1, stack)) = stack
-    expression = stack_concat(quote, (a1, expression))
-    return stack, expression
 
-CONS = SymbolJoyType('cons', [cons], 23)
-DIP = CombinatorJoyType('dip', [dip_t], 44)
+    [(s1, (f1, s1)), (s1, (i1, s1))]
 
 
-def kav(F, e):
-    #i, stack = F
-    if not e:
-        return [(F, e)]
-    n, e = e
-    if isinstance(n, SymbolJoyType):
-        Fs = []
-        for sec in n.stack_effects:
-            Fs.extend(MC([F], sec))
-        return [kav(Fn, e) for Fn in Fs]
-    if isinstance(n, CombinatorJoyType):
-        res = []
-        for f in n.stack_effects:
-            s, e = f(F[1], e)
-            new_F = F[0], s
-            res.extend(kav(new_F, e))
-        return res
-    lit = S[0], (n, S[0])
-    return [kav(Fn, e) for Fn in MC([F], [lit])]
 
+
+```python
+for stack_effect_comment in infer(expression):
+    print doc_from_stack_effect(*stack_effect_comment)
 ```
 
-compare, and be amazed:
+    (-- f1)
+    (-- i1)
+
 
 
 ```python
-def dip_t(stack, expression):
-    (quote, (a1, stack)) = stack
-    expression = stack_concat(quote, (a1, expression))
-    return stack, expression
+expression
 ```
 
 
+
+
+    (n1, (n2, (mul, ())))
+
+
+
+
 ```python
-def dip(stack, expression, dictionary):
-    (quote, (x, stack)) = stack
-    expression = (x, expression)
-    return stack, concat(quote, expression), dictionary
+infer(expression)
 ```
 
-And that brings us to current Work-In-Progress.  I'm pretty hopeful that the mixed-mode inferencer/interpreter `kav()` function along with the ability to specify multiple implementations for the combinators will permit modelling of the stack effects of e.g. `ifte`.  If I can keep up the pace I should be able to verify that conjecture by the end of June.
+
+
+
+    [(s1, (f1, s1)), (s1, (i1, s1))]
+
+
+
+And that brings us to current Work-In-Progress.  I'm pretty hopeful that the mixed-mode inferencer/interpreter `infer()` function along with the ability to specify multiple implementations for the combinators will permit modelling of the stack effects of e.g. `ifte`.  If I can keep up the pace I should be able to verify that conjecture by the end of June.
+
+## Conclusion
+(for now...)
+
+Work remains to be done:
+
+- the rest of the library has to be covered
+- figure out how to deal with `loop` and `genrec`, etc..
+- extend the types to check values (see the appendix)
+- other kinds of "higher order" type variables, OR, AND, etc..
+- maybe rewrite in Prolog for great good?
+- definitions
+  - don't permit composition of functions that don't compose
+  - auto-compile compilable functions
+- Compiling more than just the Yin functions.
+- getting better visibility (than Python debugger.)
+- DOOOOCS!!!!  Lots of docs!
+  - docstrings all around
+  - improve this notebook (it kinda falls apart at the end narratively.  I went off and just started writing code to see if it would work.  It does, but now I have to come back and describe here what I did.
+
+I'm starting to realize that, with the inferencer/checker/compiler coming along, and with the UI ready to be rewritten in Joy, I'm close to a time when my ephasis is going to have to shift from crunchy code stuff to squishy human stuff.  I'm going to have to put normal people in front of this and see if, in fact, they *can* learn the basics of programming with it.
 
 The rest of this stuff is junk and/or unfinished material.
 
@@ -2496,147 +2498,159 @@ For this to work the type label classes have to be modified to let `T >= t` succ
 
 
 ```python
-F = reduce(C, (pop, swap, rolldown, rest, rest, cons, cons))
+def _ge(self, other):
+    return (issubclass(other.__class__, self.__class__)
+            or hasattr(self, 'accept')
+            and isinstance(other, self.accept))
 
-print doc_from_stack_effect(*F)
+AnyJoyType.__ge__ = _ge
+AnyJoyType.accept = tuple, int, float, long, str, unicode, bool, Symbol
+StackJoyType.accept = tuple
 ```
 
 
-    ---------------------------------------------------------------------------
+```python
+F = infer(l2s((pop, swap, rolldown, rest, rest, cons, cons)))
 
-    TypeError                                 Traceback (most recent call last)
+for f in F:
+    print doc_from_stack_effect(*f)
+```
 
-    <ipython-input-119-7fde90b4e88f> in <module>()
-          1 F = reduce(C, (pop, swap, rolldown, rest, rest, cons, cons))
-          2 
-    ----> 3 print doc_from_stack_effect(*F)
-    
+    ([a4 a5 .1.] a3 a2 a1 -- [a2 a3 .1.])
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+```python
+from joy.parser import text_to_expression
+```
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
+```python
+F = infer(l2s((pop, pop, pop)))
 
+for f in F:
+    print doc_from_stack_effect(*f)
+```
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+    (a3 a2 a1 --)
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
+```python
+s = text_to_expression('0 1 2')
+s
+```
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
+    (0, (1, (2, ())))
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
+
+```python
+F[0][0]
+```
+
+
 
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+    (a1, (a2, (a3, s1)))
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+```python
+L = unify(s, F[0][0])
+L
+```
+
 
 
-    TypeError: 'SymbolJoyType' object is not iterable
+
+    ()
+
 
 
 
 ```python
-from joy.parser import text_to_expression
+s = text_to_expression('0 1 2 [3 4]')
+s
 ```
 
 
+
+
+    (0, (1, (2, ((3, (4, ())), ()))))
+
+
+
+
 ```python
-s = text_to_expression('[3 4 ...] 2 1')
-s
+F[0][0]
 ```
 
 
+
+
+    (a1, (a2, (a3, s1)))
+
+
+
+
 ```python
-L = unify(F[1], s)
+L = unify(s, F[0][0])
 L
 ```
 
 
+
+
+    ()
+
+
+
+
 ```python
-F[1]
+L = unify(F[0][0], s)
+L
 ```
 
 
+
+
+    ()
+
+
+
+
 ```python
 F[1][0]
 ```
 
 
+    ---------------------------------------------------------------------------
+
+    IndexError                                Traceback (most recent call last)
+
+    <ipython-input-133-58a8e44e9cba> in <module>()
+    ----> 1 F[1][0]
+    
+
+    IndexError: list index out of range
+
+
+
 ```python
 s[0]
 ```
 
+
+```python
+A[1] >= 23
+```
+
 ## [Abstract Interpretation](https://en.wikipedia.org/wiki/Abstract_interpretation)
 I *think* this might be sorta what I'm doing above with the `kav()` function...
   In any event "mixed-mode" interpreters that include values and type variables and can track constraints, etc. will be, uh, super-useful.  And Abstract Interpretation should be a rich source of ideas.
index 216ce90..a8084de 100644 (file)
@@ -3,42 +3,19 @@ Type Inference
 ==============
 
 This notebook presents a simple type inferencer for Joy code. It can
-infer the stack effect of most Joy expressions. It built largely by
-means of existing ideas and research (some of it may be original but I'm
-not able to say, as I don't fully understand the all of the source
-material in the depth required to make that call.) A great overview of
-the existing knowledge is a talk `"Type Inference in Stack-Based
-Programming
+infer the stack effect of most Joy expressions. It's built largely by
+means of existing ideas and research. (A great overview of the existing
+knowledge is a talk `"Type Inference in Stack-Based Programming
 Languages" <http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/>`__
 given by Rob Kleffner on or about 2017-03-10 as part of a course on the
-history of programming languages.
+history of programming languages.)
 
 The notebook starts with a simple inferencer based on the work of Jaanus
 Pöial which we then progressively elaborate to cover more Joy semantics.
 Along the way we write a simple "compiler" that emits Python code for
-what I like to call Yin functions.
-
-Yin functions are those that only rearrange values in stacks, as opposed
-to Yang functions that actually work on the values themselves. It's
-interesting to note that a Joy with *only* stacks (no other kinds of
-values) can be made and is Turing-complete, therefore all Yang functions
-are actually Yin functions, and all computation can be performed by
-manipulations of structures of containers, which is a restatement of the
-Laws of Form. (Also, this implies that every program can be put into a
-form such that it can be computed in a single step, although that step
-may be enormous or unending.)
-
-Although I haven't completed it yet, a Joy based on Laws of Form
-provides the foundation for a provably correct computing system "down to
-the metal". This is my original and still primary motivation for
-developing Joy. (I want a proven-correct Operating System for a swarm of
-trash-collecting recycler robots. To trust it I have to implementment it
-myself from first principles, and I'm not smart enough to truly grok the
-existing literature and software, so I had to go look for and find LoF
-and Joy. Now that I have the mental tools to build my robot OS I can get
-down to it.
-
-Anyhow, here's type inference...
+what I like to call Yin functions. (Yin functions are those that only
+rearrange values in stacks, as opposed to Yang functions that actually
+work on the values themselves.)
 
 Part I: Pöial's Rules
 ---------------------
@@ -235,8 +212,8 @@ function only rearranges the stack and doesn't do any actual processing
 on the stack items themselves all the information needed to implement it
 is in the stack effect comment.
 
-Functions on Lists
-~~~~~~~~~~~~~~~~~~
+Functions on Stacks
+~~~~~~~~~~~~~~~~~~~
 
 These are slightly tricky.
 
@@ -495,18 +472,12 @@ integers or tuples of type descriptors:
         if s is None:
             s = {}
     
-        if u == v:
-            return s
-    
         if isinstance(u, int):
             s[u] = v
-            return s
-    
-        if isinstance(v, int):
+        elif isinstance(v, int):
             s[v] = u
-            return s
     
-        return False
+        return s
 
 ``update()``
 ~~~~~~~~~~~~
@@ -738,12 +709,6 @@ work:
     except Exception, e:
         print e
 
-
-.. parsed-literal::
-
-    Cannot unify (1, 2) and (1001, 1002).
-
-
 ``unify()`` version 2
 ^^^^^^^^^^^^^^^^^^^^^
 
@@ -760,27 +725,24 @@ deal with this recursively:
             u = update(s, u)
             v = update(s, v)
     
-        if u == v:
-            return s
-    
         if isinstance(u, int):
             s[u] = v
-            return s
     
-        if isinstance(v, int):
+        elif isinstance(v, int):
             s[v] = u
-            return s
     
-        if isinstance(u, tuple) and isinstance(v, tuple):
-            if len(u) != len(v) != 2:
-                raise ValueError(repr((u, v)))
-            for uu, vv in zip(u, v):
-                s = unify(uu, vv, s)
-                if s == False: # (instead of a substitution dict.)
-                    break
-            return s
-     
-        return False
+        elif isinstance(u, tuple) and isinstance(v, tuple):
+    
+            if len(u) != 2 or len(v) != 2:
+                # Not a type error, caller passed in a bad value.
+                raise ValueError(repr((u, v)))  # FIXME this message sucks.
+    
+            (a, b), (c, d) = u, v
+            s = unify(a, c, s)
+            if s != False:
+                s = unify(b, d, s)
+    
+        return s
 
 .. code:: ipython2
 
@@ -1406,7 +1368,7 @@ of how many labels of each domain it has "seen".
             pass
     
         if not isinstance(f, tuple):
-            seen[f] = f.__class__(c[f.prefix])
+            seen[f] = f.__class__(c[f.prefix] + 1)
             c[f.prefix] += 1
             return seen[f]
     
@@ -1421,7 +1383,7 @@ of how many labels of each domain it has "seen".
 
 .. parsed-literal::
 
-    (((a0,), (a0, a0)), ((n0, n1), (n2,)))
+    (((a1,), (a1, a1)), ((n1, n2), (n3,)))
 
 
 
@@ -1544,7 +1506,7 @@ Rewrite the stack effect comments:
 
 .. parsed-literal::
 
-    ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+    ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
     cons = (a1 [.1.] -- [a1 .1.])
     divmod_ = (n2 n1 -- n4 n3)
     dup = (a1 -- a1 a1)
@@ -1561,13 +1523,13 @@ Rewrite the stack effect comments:
     rest = ([a1 .1.] -- [.1.])
     rolldown = (a1 a2 a3 -- a2 a3 a1)
     rollup = (a1 a2 a3 -- a3 a1 a2)
-    rrest = ([a0 a1 .0.] -- [.0.])
-    second = ([a0 a1 .0.] -- a1)
-    sqrt = (n0 -- n1)
+    rrest = ([a1 a2 .1.] -- [.1.])
+    second = ([a1 a2 .1.] -- a2)
+    sqrt = (n1 -- n2)
     succ = (n1 -- n2)
     swap = (a1 a2 -- a2 a1)
-    swons = ([.0.] a0 -- [a0 .0.])
-    third = ([a0 a1 a2 .0.] -- a2)
+    swons = ([.1.] a1 -- [a1 .1.])
+    third = ([a1 a2 a3 .1.] -- a3)
     tuck = (a2 a1 -- a1 a2 a1)
     uncons = ([a1 .1.] -- a1 [.1.])
 
@@ -1588,7 +1550,7 @@ Compose ``dup`` and ``mul``
 
 .. parsed-literal::
 
-    ((n0,), (n1,))
+    ((n1,), (n2,))
 
 
 
@@ -1604,7 +1566,7 @@ Revisit the ``F`` function, works fine.
 
 .. parsed-literal::
 
-    (((a0, (a1, s0)), a2, a3, a4), ((a3, (a2, s0)),))
+    (((a1, (a2, s1)), a3, a4, a5), ((a4, (a3, s1)),))
 
 
 
@@ -1615,7 +1577,7 @@ Revisit the ``F`` function, works fine.
 
 .. parsed-literal::
 
-    ([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])
+    ([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])
 
 
 Some otherwise inefficient functions are no longer to be feared. We can
@@ -1634,7 +1596,7 @@ also get the effect of combinators in some limited cases.
 
 .. parsed-literal::
 
-    (a0 a1 a2 -- a1 a0 a2)
+    (a1 a2 a3 -- a2 a1 a3)
 
 
 .. code:: ipython2
@@ -1645,7 +1607,7 @@ also get the effect of combinators in some limited cases.
 
 .. parsed-literal::
 
-    (a0 a1 a2 a3 -- a2 a3)
+    (a1 a2 a3 a4 -- a3 a4)
 
 
 .. code:: ipython2
@@ -1656,7 +1618,7 @@ also get the effect of combinators in some limited cases.
 
 .. parsed-literal::
 
-    (a0 a1 a2 -- a2 a1 a0)
+    (a1 a2 a3 -- a3 a2 a1)
 
 
 ``compile_()`` version 2
@@ -1689,9 +1651,9 @@ the ``compile_()`` function doesn't need to generate them anymore:
 .. parsed-literal::
 
     def F(stack):
-        """([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])"""
-        (a4, (a3, (a2, ((a0, (a1, s0)), stack)))) = stack
-        return ((a3, (a2, s0)), stack)
+        """([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])"""
+        (a5, (a4, (a3, ((a1, (a2, s1)), stack)))) = stack
+        return ((a4, (a3, s1)), stack)
 
 
 But it cannot magically create new functions that involve e.g. math and
@@ -1705,9 +1667,9 @@ such. Note that this is *not* a ``sqr`` function implementation:
 .. parsed-literal::
 
     def sqr(stack):
-        """(n0 -- n1)"""
-        (n0, stack) = stack
-        return (n1, stack)
+        """(n1 -- n2)"""
+        (n1, stack) = stack
+        return (n2, stack)
 
 
 (Eventually I should come back around to this becuase it's not tooo
@@ -1742,7 +1704,7 @@ comments. We can write a function to check that:
 
 .. parsed-literal::
 
-    ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+    ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
     cons = (a1 [.1.] -- [a1 .1.])
     dup = (a1 -- a1 a1)
     dupd = (a2 a1 -- a2 a2 a1)
@@ -1755,11 +1717,11 @@ comments. We can write a function to check that:
     rest = ([a1 .1.] -- [.1.])
     rolldown = (a1 a2 a3 -- a2 a3 a1)
     rollup = (a1 a2 a3 -- a3 a1 a2)
-    rrest = ([a0 a1 .0.] -- [.0.])
-    second = ([a0 a1 .0.] -- a1)
+    rrest = ([a1 a2 .1.] -- [.1.])
+    second = ([a1 a2 .1.] -- a2)
     swap = (a1 a2 -- a2 a1)
-    swons = ([.0.] a0 -- [a0 .0.])
-    third = ([a0 a1 a2 .0.] -- a2)
+    swons = ([.1.] a1 -- [a1 .1.])
+    third = ([a1 a2 a3 .1.] -- a3)
     tuck = (a2 a1 -- a1 a2 a1)
     uncons = ([a1 .1.] -- a1 [.1.])
 
@@ -1849,7 +1811,13 @@ It works.
 This function has to be modified to use the new datastructures and it is
 no longer recursive, instead recursion happens as part of unification.
 Further, the first and second of Pöial's rules are now handled
-automatically by the unification algorithm.
+automatically by the unification algorithm. (One easy way to see this is
+that now an empty stack effect comment is represented by a
+``StackJoyType`` instance which is not "falsey" and so neither of the
+first two rules' ``if`` clauses will ever be ``True``. Later on I change
+the "truthiness" of ``StackJoyType`` to false to let e.g.
+``joy.utils.stack.concat`` work with our stack effect comment cons-list
+tuples.)
 
 .. code:: ipython2
 
@@ -1886,20 +1854,20 @@ conversion function instead. This is programmer's laziness.
 
 .. parsed-literal::
 
-    ((a0, s0), (s0, (a0, (a0, s0))))
+    ((a1, s1), (s1, (a1, (a1, s1))))
 
 
 
 .. code:: ipython2
 
-    C(C(stack, uncons), uncons)
+    reduce(C, (stack, uncons, uncons))
 
 
 
 
 .. parsed-literal::
 
-    ((a0, (a1, s0)), (s0, (a1, (a0, (a0, (a1, s0))))))
+    ((a1, (a2, s1)), (s1, (a2, (a1, (a1, (a2, s1))))))
 
 
 
@@ -1966,7 +1934,7 @@ Clunky junk, but it will suffice for now.
 
 .. parsed-literal::
 
-    ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+    ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
     cons = (a1 [.1.] -- [a1 .1.])
     divmod_ = (n2 n1 -- n4 n3)
     dup = (a1 -- a1 a1)
@@ -1983,15 +1951,15 @@ Clunky junk, but it will suffice for now.
     rest = ([a1 .1.] -- [.1.])
     rolldown = (a1 a2 a3 -- a2 a3 a1)
     rollup = (a1 a2 a3 -- a3 a1 a2)
-    rrest = ([a0 a1 .0.] -- [.0.])
-    second = ([a0 a1 .0.] -- a1)
-    sqrt = (n0 -- n1)
+    rrest = ([a1 a2 .1.] -- [.1.])
+    second = ([a1 a2 .1.] -- a2)
+    sqrt = (n1 -- n2)
     stack = (... -- ... [...])
     succ = (n1 -- n2)
     swaack = ([.1.] -- [.0.])
     swap = (a1 a2 -- a2 a1)
-    swons = ([.0.] a0 -- [a0 .0.])
-    third = ([a0 a1 a2 .0.] -- a2)
+    swons = ([.1.] a1 -- [a1 .1.])
+    third = ([a1 a2 a3 .1.] -- a3)
     tuck = (a2 a1 -- a1 a2 a1)
     uncons = ([a1 .1.] -- a1 [.1.])
 
@@ -2000,8 +1968,8 @@ Clunky junk, but it will suffice for now.
 
     print ; print doc_from_stack_effect(*stack)
     print ; print doc_from_stack_effect(*C(stack, uncons))
-    print ; print doc_from_stack_effect(*C(C(stack, uncons), uncons))
-    print ; print doc_from_stack_effect(*C(C(stack, uncons), cons))
+    print ; print doc_from_stack_effect(*reduce(C, (stack, uncons, uncons)))
+    print ; print doc_from_stack_effect(*reduce(C, (stack, uncons, cons)))
 
 
 .. parsed-literal::
@@ -2009,11 +1977,11 @@ Clunky junk, but it will suffice for now.
     
     (... -- ... [...])
     
-    (... a0 -- ... a0 a0 [...])
+    (... a1 -- ... a1 a1 [...])
     
-    (... a1 a0 -- ... a1 a0 a0 a1 [...])
+    (... a2 a1 -- ... a2 a1 a1 a2 [...])
     
-    (... a0 -- ... a0 [a0 ...])
+    (... a1 -- ... a1 [a1 ...])
 
 
 .. code:: ipython2
@@ -2023,7 +1991,7 @@ Clunky junk, but it will suffice for now.
 
 .. parsed-literal::
 
-    (... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])
+    (... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])
 
 
 .. code:: ipython2
@@ -2037,7 +2005,7 @@ Clunky junk, but it will suffice for now.
 
 .. parsed-literal::
 
-    ((s0, (a0, (a1, s1))), (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1)))
+    ((s1, (a1, (a2, s2))), (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2)))
 
 
 
@@ -2066,9 +2034,9 @@ comments are now already in the form needed for the Python code:
 .. parsed-literal::
 
     def Q(stack):
-        """(... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])"""
-        (s0, (a0, (a1, s1))) = stack
-        return (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1))
+        """(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])"""
+        (s1, (a1, (a2, s2))) = stack
+        return (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2))
 
 
 .. code:: ipython2
@@ -2103,7 +2071,7 @@ comments are now already in the form needed for the Python code:
 
 .. parsed-literal::
 
-    (a0 [.0.] -- a0)
+    (a1 [.1.] -- a1)
 
 
 .. code:: ipython2
@@ -2113,7 +2081,7 @@ comments are now already in the form needed for the Python code:
 
 .. parsed-literal::
 
-    (a0 [.0.] -- [[a0 .0.] .1.])
+    (a1 [.1.] -- [[a1 .1.] .2.])
 
 
 .. code:: ipython2
@@ -2125,7 +2093,7 @@ comments are now already in the form needed for the Python code:
 
 .. parsed-literal::
 
-    ((s0, (a0, s1)), (a0, s0))
+    ((s1, (a1, s2)), (a1, s1))
 
 
 
@@ -2177,8 +2145,8 @@ Part VI: Multiple Stack Effects
 
 .. parsed-literal::
 
-    (a1 -- a1 a1) (i1 i2 -- i3) (i0 -- i1)
-    (a1 -- a1 a1) (f1 f2 -- f3) (f0 -- f1)
+    (a1 -- a1 a1) (i1 i2 -- i3) (i1 -- i2)
+    (a1 -- a1 a1) (f1 f2 -- f3) (f1 -- f2)
 
 
 .. code:: ipython2
@@ -2199,25 +2167,25 @@ Part VI: Multiple Stack Effects
 
 .. code:: ipython2
 
-    for f in MC([dup], muls):
+    for f in MC([dup], [mul]):
         print doc_from_stack_effect(*f)
 
 
 .. parsed-literal::
 
-    (f0 -- f1)
-    (i0 -- i1)
+    (n1 -- n2)
 
 
 .. code:: ipython2
 
-    for f in MC([dup], [mul]):
+    for f in MC([dup], muls):
         print doc_from_stack_effect(*f)
 
 
 .. parsed-literal::
 
-    (n0 -- n1)
+    (f1 -- f2)
+    (i1 -- i2)
 
 
 Representing an Unbounded Sequence of Types
@@ -2541,8 +2509,8 @@ This function has to be modified to yield multiple results.
 
 .. parsed-literal::
 
-    (f0 -- f1)
-    (i0 -- i1)
+    (f1 -- f2)
+    (i1 -- i2)
 
 
 .. code:: ipython2
@@ -2555,7 +2523,7 @@ This function has to be modified to yield multiple results.
 
 .. parsed-literal::
 
-    ([n0* .0.] -- [n0* .0.] n0)
+    ([n1* .1.] -- [n1* .1.] n1)
 
 
 .. code:: ipython2
@@ -2568,8 +2536,8 @@ This function has to be modified to yield multiple results.
 
 .. parsed-literal::
 
-    (a0 [.0.] -- n0)
-    (n0 [n0* .0.] -- n1)
+    (a1 [.1.] -- n1)
+    (n1 [n1* .1.] -- n2)
 
 
 .. code:: ipython2
@@ -2584,7 +2552,7 @@ This function has to be modified to yield multiple results.
 
 .. parsed-literal::
 
-    (a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n0 [n0* .0.] -- n1)
+    (a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n1 [n1* .1.] -- n2)
 
 
 .. code:: ipython2
@@ -2828,6 +2796,19 @@ stack effect we have to "split universes" again and return both.
 
 .. code:: ipython2
 
+    expression
+
+
+
+
+.. parsed-literal::
+
+    (n1, (n2, (mul, ())))
+
+
+
+.. code:: ipython2
+
     infer(expression)
 
 
@@ -2835,74 +2816,97 @@ stack effect we have to "split universes" again and return both.
 
 .. parsed-literal::
 
-    []
+    [(s1, (f1, s1)), (s1, (i1, s1))]
 
 
 
 .. code:: ipython2
 
-    class SymbolJoyType(AnyJoyType):
-        prefix = 'F'
-    
-        def __init__(self, name, sec, number):
-            self.name = name
-            self.stack_effects = sec
-            self.number = number
-    
-    class CombinatorJoyType(SymbolJoyType): prefix = 'C'
-    
-    def dip_t(stack, expression):
-        (quote, (a1, stack)) = stack
-        expression = stack_concat(quote, (a1, expression))
-        return stack, expression
-    
-    CONS = SymbolJoyType('cons', [cons], 23)
-    DIP = CombinatorJoyType('dip', [dip_t], 44)
-    
-    
-    def kav(F, e):
-        #i, stack = F
-        if not e:
-            return [(F, e)]
-        n, e = e
-        if isinstance(n, SymbolJoyType):
-            Fs = []
-            for sec in n.stack_effects:
-                Fs.extend(MC([F], sec))
-            return [kav(Fn, e) for Fn in Fs]
-        if isinstance(n, CombinatorJoyType):
-            res = []
-            for f in n.stack_effects:
-                s, e = f(F[1], e)
-                new_F = F[0], s
-                res.extend(kav(new_F, e))
-            return res
-        lit = S[0], (n, S[0])
-        return [kav(Fn, e) for Fn in MC([F], [lit])]
+    infer(expression)
+
+
+
+
+.. parsed-literal::
+
+    [(s1, (f1, s1)), (s1, (i1, s1))]
 
 
-compare, and be amazed:
 
 .. code:: ipython2
 
-    def dip_t(stack, expression):
-        (quote, (a1, stack)) = stack
-        expression = stack_concat(quote, (a1, expression))
-        return stack, expression
+    for stack_effect_comment in infer(expression):
+        print doc_from_stack_effect(*stack_effect_comment)
+
+
+.. parsed-literal::
+
+    (-- f1)
+    (-- i1)
+
+
+.. code:: ipython2
+
+    expression
+
+
+
+
+.. parsed-literal::
+
+    (n1, (n2, (mul, ())))
+
+
 
 .. code:: ipython2
 
-    def dip(stack, expression, dictionary):
-        (quote, (x, stack)) = stack
-        expression = (x, expression)
-        return stack, concat(quote, expression), dictionary
+    infer(expression)
+
+
+
+
+.. parsed-literal::
+
+    [(s1, (f1, s1)), (s1, (i1, s1))]
+
+
 
 And that brings us to current Work-In-Progress. I'm pretty hopeful that
-the mixed-mode inferencer/interpreter ``kav()`` function along with the
-ability to specify multiple implementations for the combinators will
+the mixed-mode inferencer/interpreter ``infer()`` function along with
+the ability to specify multiple implementations for the combinators will
 permit modelling of the stack effects of e.g. ``ifte``. If I can keep up
 the pace I should be able to verify that conjecture by the end of June.
 
+Conclusion
+----------
+
+(for now...)
+
+Work remains to be done:
+
+-  the rest of the library has to be covered
+-  figure out how to deal with ``loop`` and ``genrec``, etc..
+-  extend the types to check values (see the appendix)
+-  other kinds of "higher order" type variables, OR, AND, etc..
+-  maybe rewrite in Prolog for great good?
+-  definitions
+-  don't permit composition of functions that don't compose
+-  auto-compile compilable functions
+-  Compiling more than just the Yin functions.
+-  getting better visibility (than Python debugger.)
+-  DOOOOCS!!!! Lots of docs!
+-  docstrings all around
+-  improve this notebook (it kinda falls apart at the end narratively. I
+   went off and just started writing code to see if it would work. It
+   does, but now I have to come back and describe here what I did.
+
+I'm starting to realize that, with the inferencer/checker/compiler
+coming along, and with the UI ready to be rewritten in Joy, I'm close to
+a time when my ephasis is going to have to shift from crunchy code stuff
+to squishy human stuff. I'm going to have to put normal people in front
+of this and see if, in fact, they *can* learn the basics of programming
+with it.
+
 The rest of this stuff is junk and/or unfinished material.
 
 Appendix: Joy in the Logical Paradigm
@@ -2914,143 +2918,168 @@ For this to work the type label classes have to be modified to let
 
 .. code:: ipython2
 
-    F = reduce(C, (pop, swap, rolldown, rest, rest, cons, cons))
+    def _ge(self, other):
+        return (issubclass(other.__class__, self.__class__)
+                or hasattr(self, 'accept')
+                and isinstance(other, self.accept))
     
-    print doc_from_stack_effect(*F)
+    AnyJoyType.__ge__ = _ge
+    AnyJoyType.accept = tuple, int, float, long, str, unicode, bool, Symbol
+    StackJoyType.accept = tuple
 
+.. code:: ipython2
 
-::
+    F = infer(l2s((pop, swap, rolldown, rest, rest, cons, cons)))
+    
+    for f in F:
+        print doc_from_stack_effect(*f)
 
 
-    ---------------------------------------------------------------------------
+.. parsed-literal::
 
-    TypeError                                 Traceback (most recent call last)
+    ([a4 a5 .1.] a3 a2 a1 -- [a2 a3 .1.])
 
-    <ipython-input-119-7fde90b4e88f> in <module>()
-          1 F = reduce(C, (pop, swap, rolldown, rest, rest, cons, cons))
-          2 
-    ----> 3 print doc_from_stack_effect(*F)
-    
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
+.. code:: ipython2
 
+    from joy.parser import text_to_expression
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+.. code:: ipython2
 
+    F = infer(l2s((pop, pop, pop)))
+    
+    for f in F:
+        print doc_from_stack_effect(*f)
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
+.. parsed-literal::
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+    (a3 a2 a1 --)
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
+.. code:: ipython2
 
+    s = text_to_expression('0 1 2')
+    s
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
+.. parsed-literal::
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+    (0, (1, (2, ())))
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
+.. code:: ipython2
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+    F[0][0]
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+.. parsed-literal::
 
+    (a1, (a2, (a3, s1)))
 
-    TypeError: 'SymbolJoyType' object is not iterable
 
 
 .. code:: ipython2
 
-    from joy.parser import text_to_expression
+    L = unify(s, F[0][0])
+    L
+
+
+
+
+.. parsed-literal::
+
+    ()
+
+
 
 .. code:: ipython2
 
-    s = text_to_expression('[3 4 ...] 2 1')
+    s = text_to_expression('0 1 2 [3 4]')
     s
 
+
+
+
+.. parsed-literal::
+
+    (0, (1, (2, ((3, (4, ())), ()))))
+
+
+
 .. code:: ipython2
 
-    L = unify(F[1], s)
+    F[0][0]
+
+
+
+
+.. parsed-literal::
+
+    (a1, (a2, (a3, s1)))
+
+
+
+.. code:: ipython2
+
+    L = unify(s, F[0][0])
     L
 
+
+
+
+.. parsed-literal::
+
+    ()
+
+
+
 .. code:: ipython2
 
-    F[1]
+    L = unify(F[0][0], s)
+    L
+
+
+
+
+.. parsed-literal::
+
+    ()
+
+
 
 .. code:: ipython2
 
     F[1][0]
 
+
+::
+
+
+    ---------------------------------------------------------------------------
+
+    IndexError                                Traceback (most recent call last)
+
+    <ipython-input-133-58a8e44e9cba> in <module>()
+    ----> 1 F[1][0]
+    
+
+    IndexError: list index out of range
+
+
 .. code:: ipython2
 
     s[0]
 
+.. code:: ipython2
+
+    A[1] >= 23
+
 `Abstract Interpretation <https://en.wikipedia.org/wiki/Abstract_interpretation>`__
 -----------------------------------------------------------------------------------
 
index 2288a36..a6d4450 100644 (file)
   <div class="section" id="type-inference">
 <h1>Type Inference<a class="headerlink" href="#type-inference" title="Permalink to this headline">¶</a></h1>
 <p>This notebook presents a simple type inferencer for Joy code. It can
-infer the stack effect of most Joy expressions. It built largely by
-means of existing ideas and research (some of it may be original but I’m
-not able to say, as I don’t fully understand the all of the source
-material in the depth required to make that call.) A great overview of
-the existing knowledge is a talk <a class="reference external" href="http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/">“Type Inference in Stack-Based
-Programming
+infer the stack effect of most Joy expressions. It’s built largely by
+means of existing ideas and research. (A great overview of the existing
+knowledge is a talk <a class="reference external" href="http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/">“Type Inference in Stack-Based Programming
 Languages”</a>
 given by Rob Kleffner on or about 2017-03-10 as part of a course on the
-history of programming languages.</p>
+history of programming languages.)</p>
 <p>The notebook starts with a simple inferencer based on the work of Jaanus
 Pöial which we then progressively elaborate to cover more Joy semantics.
 Along the way we write a simple “compiler” that emits Python code for
-what I like to call Yin functions.</p>
-<p>Yin functions are those that only rearrange values in stacks, as opposed
-to Yang functions that actually work on the values themselves. It’s
-interesting to note that a Joy with <em>only</em> stacks (no other kinds of
-values) can be made and is Turing-complete, therefore all Yang functions
-are actually Yin functions, and all computation can be performed by
-manipulations of structures of containers, which is a restatement of the
-Laws of Form. (Also, this implies that every program can be put into a
-form such that it can be computed in a single step, although that step
-may be enormous or unending.)</p>
-<p>Although I haven’t completed it yet, a Joy based on Laws of Form
-provides the foundation for a provably correct computing system “down to
-the metal”. This is my original and still primary motivation for
-developing Joy. (I want a proven-correct Operating System for a swarm of
-trash-collecting recycler robots. To trust it I have to implementment it
-myself from first principles, and I’m not smart enough to truly grok the
-existing literature and software, so I had to go look for and find LoF
-and Joy. Now that I have the mental tools to build my robot OS I can get
-down to it.</p>
-<p>Anyhow, here’s type inference…</p>
+what I like to call Yin functions. (Yin functions are those that only
+rearrange values in stacks, as opposed to Yang functions that actually
+work on the values themselves.)</p>
 <div class="section" id="part-i-poial-s-rules">
 <h2>Part I: Pöial’s Rules<a class="headerlink" href="#part-i-poial-s-rules" title="Permalink to this headline">¶</a></h2>
 <p><a class="reference external" href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.212.6026">“Typing Tools for Typeless Stack Languages” by Jaanus
@@ -222,8 +202,8 @@ function only rearranges the stack and doesn’t do any actual processing
 on the stack items themselves all the information needed to implement it
 is in the stack effect comment.</p>
 </div>
-<div class="section" id="functions-on-lists">
-<h3>Functions on Lists<a class="headerlink" href="#functions-on-lists" title="Permalink to this headline">¶</a></h3>
+<div class="section" id="functions-on-stacks">
+<h3>Functions on Stacks<a class="headerlink" href="#functions-on-stacks" title="Permalink to this headline">¶</a></h3>
 <p>These are slightly tricky.</p>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rest</span> <span class="p">(</span> <span class="p">[</span><span class="mi">1</span> <span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span> <span class="p">)</span>
 
@@ -426,18 +406,12 @@ integers or tuples of type descriptors:</p>
     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
 
-    <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
-        <span class="k">return</span> <span class="n">s</span>
-
     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
-        <span class="k">return</span> <span class="n">s</span>
-
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
-        <span class="k">return</span> <span class="n">s</span>
 
-    <span class="k">return</span> <span class="kc">False</span>
+    <span class="k">return</span> <span class="n">s</span>
 </pre></div>
 </div>
 </div>
@@ -592,9 +566,6 @@ work:</p>
     <span class="nb">print</span> <span class="n">e</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Cannot</span> <span class="n">unify</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="mi">1001</span><span class="p">,</span> <span class="mi">1002</span><span class="p">)</span><span class="o">.</span>
-</pre></div>
-</div>
 <div class="section" id="unify-version-2">
 <h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 2<a class="headerlink" href="#unify-version-2" title="Permalink to this headline">¶</a></h4>
 <p>The problem is that the <code class="docutils literal notranslate"><span class="pre">unify()</span></code> function as written doesn’t handle
@@ -607,27 +578,24 @@ deal with this recursively:</p>
         <span class="n">u</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">u</span><span class="p">)</span>
         <span class="n">v</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
 
-    <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
-        <span class="k">return</span> <span class="n">s</span>
-
     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
-        <span class="k">return</span> <span class="n">s</span>
 
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
+    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
-        <span class="k">return</span> <span class="n">s</span>
 
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
-        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
-            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>
-        <span class="k">for</span> <span class="n">uu</span><span class="p">,</span> <span class="n">vv</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">):</span>
-            <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">uu</span><span class="p">,</span> <span class="n">vv</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
-            <span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span> <span class="c1"># (instead of a substitution dict.)</span>
-                <span class="k">break</span>
-        <span class="k">return</span> <span class="n">s</span>
+    <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
 
-    <span class="k">return</span> <span class="kc">False</span>
+        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
+            <span class="c1"># Not a type error, caller passed in a bad value.</span>
+            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>  <span class="c1"># FIXME this message sucks.</span>
+
+        <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">),</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span> <span class="o">=</span> <span class="n">u</span><span class="p">,</span> <span class="n">v</span>
+        <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
+        <span class="k">if</span> <span class="n">s</span> <span class="o">!=</span> <span class="kc">False</span><span class="p">:</span>
+            <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
+
+    <span class="k">return</span> <span class="n">s</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
@@ -1122,7 +1090,7 @@ of how many labels of each domain it has “seen”.</p>
         <span class="k">pass</span>
 
     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
-        <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">])</span>
+        <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
         <span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
         <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
 
@@ -1132,7 +1100,7 @@ of how many labels of each domain it has “seen”.</p>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">delabel</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a0</span><span class="p">,),</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">a0</span><span class="p">)),</span> <span class="p">((</span><span class="n">n0</span><span class="p">,</span> <span class="n">n1</span><span class="p">),</span> <span class="p">(</span><span class="n">n2</span><span class="p">,)))</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a1</span><span class="p">,),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a1</span><span class="p">)),</span> <span class="p">((</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">),</span> <span class="p">(</span><span class="n">n3</span><span class="p">,)))</span>
 </pre></div>
 </div>
 </div>
@@ -1246,7 +1214,7 @@ of how many labels of each domain it has “seen”.</p>
     <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ccons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a0</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ccons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 <span class="n">divmod_</span> <span class="o">=</span> <span class="p">(</span><span class="n">n2</span> <span class="n">n1</span> <span class="o">--</span> <span class="n">n4</span> <span class="n">n3</span><span class="p">)</span>
 <span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span>
@@ -1263,13 +1231,13 @@ of how many labels of each domain it has “seen”.</p>
 <span class="n">rest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a1</span><span class="p">)</span>
 <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
-<span class="n">rrest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
-<span class="n">second</span> <span class="o">=</span> <span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
-<span class="n">sqrt</span> <span class="o">=</span> <span class="p">(</span><span class="n">n0</span> <span class="o">--</span> <span class="n">n1</span><span class="p">)</span>
+<span class="n">rrest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
+<span class="n">second</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
+<span class="n">sqrt</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
 <span class="n">succ</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
 <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
-<span class="n">swons</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">a0</span> <span class="o">--</span> <span class="p">[</span><span class="n">a0</span> <span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
-<span class="n">third</span> <span class="o">=</span> <span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
+<span class="n">swons</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
+<span class="n">third</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a3</span><span class="p">)</span>
 <span class="n">tuck</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
 <span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 </pre></div>
@@ -1283,7 +1251,7 @@ of how many labels of each domain it has “seen”.</p>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">n0</span><span class="p">,),</span> <span class="p">(</span><span class="n">n1</span><span class="p">,))</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">n1</span><span class="p">,),</span> <span class="p">(</span><span class="n">n2</span><span class="p">,))</span>
 </pre></div>
 </div>
 <p>Revisit the <code class="docutils literal notranslate"><span class="pre">F</span></code> function, works fine.</p>
@@ -1291,13 +1259,13 @@ of how many labels of each domain it has “seen”.</p>
 <span class="n">F</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s0</span><span class="p">)),</span> <span class="n">a2</span><span class="p">,</span> <span class="n">a3</span><span class="p">,</span> <span class="n">a4</span><span class="p">),</span> <span class="p">((</span><span class="n">a3</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s0</span><span class="p">)),))</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">a3</span><span class="p">,</span> <span class="n">a4</span><span class="p">,</span> <span class="n">a5</span><span class="p">),</span> <span class="p">((</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),))</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a4</span> <span class="o">--</span> <span class="p">[</span><span class="n">a3</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a3</span> <span class="n">a4</span> <span class="n">a5</span> <span class="o">--</span> <span class="p">[</span><span class="n">a4</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 </pre></div>
 </div>
 <p>Some otherwise inefficient functions are no longer to be feared. We can
@@ -1310,21 +1278,21 @@ also get the effect of combinators in some limited cases.</p>
 <span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a0</span> <span class="n">a1</span> <span class="n">a2</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a0</span> <span class="n">a2</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a3</span><span class="p">)</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [popop] dipd</span>
 <span class="n">neato</span><span class="p">(</span><span class="n">popdd</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">pop</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a0</span> <span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a3</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a4</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a4</span><span class="p">)</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Reverse the order of the top three items.</span>
 <span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a0</span> <span class="n">a1</span> <span class="n">a2</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a0</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
 </pre></div>
 </div>
 </div>
@@ -1351,9 +1319,9 @@ the <code class="docutils literal notranslate"><span class="pre">compile_()</spa
 </pre></div>
 </div>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
-    <span class="sd">&quot;&quot;&quot;([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])&quot;&quot;&quot;</span>
-    <span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">((</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
-    <span class="k">return</span> <span class="p">((</span><span class="n">a3</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
+    <span class="sd">&quot;&quot;&quot;([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])&quot;&quot;&quot;</span>
+    <span class="p">(</span><span class="n">a5</span><span class="p">,</span> <span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
+    <span class="k">return</span> <span class="p">((</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
 </pre></div>
 </div>
 <p>But it cannot magically create new functions that involve e.g. math and
@@ -1362,9 +1330,9 @@ such. Note that this is <em>not</em> a <code class="docutils literal notranslate
 </pre></div>
 </div>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sqr</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
-    <span class="sd">&quot;&quot;&quot;(n0 -- n1)&quot;&quot;&quot;</span>
-    <span class="p">(</span><span class="n">n0</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
-    <span class="k">return</span> <span class="p">(</span><span class="n">n1</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
+    <span class="sd">&quot;&quot;&quot;(n1 -- n2)&quot;&quot;&quot;</span>
+    <span class="p">(</span><span class="n">n1</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
+    <span class="k">return</span> <span class="p">(</span><span class="n">n2</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
 </pre></div>
 </div>
 <p>(Eventually I should come back around to this becuase it’s not tooo
@@ -1392,7 +1360,7 @@ comments. We can write a function to check that:</p>
         <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ccons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a0</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ccons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 <span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span>
 <span class="n">dupd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
@@ -1405,11 +1373,11 @@ comments. We can write a function to check that:</p>
 <span class="n">rest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a1</span><span class="p">)</span>
 <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
-<span class="n">rrest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
-<span class="n">second</span> <span class="o">=</span> <span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
+<span class="n">rrest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
+<span class="n">second</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
 <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
-<span class="n">swons</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">a0</span> <span class="o">--</span> <span class="p">[</span><span class="n">a0</span> <span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
-<span class="n">third</span> <span class="o">=</span> <span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
+<span class="n">swons</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
+<span class="n">third</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a3</span><span class="p">)</span>
 <span class="n">tuck</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
 <span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 </pre></div>
@@ -1482,7 +1450,13 @@ sequence and <code class="docutils literal notranslate"><span class="pre">unify(
 <p>This function has to be modified to use the new datastructures and it is
 no longer recursive, instead recursion happens as part of unification.
 Further, the first and second of Pöial’s rules are now handled
-automatically by the unification algorithm.</p>
+automatically by the unification algorithm. (One easy way to see this is
+that now an empty stack effect comment is represented by a
+<code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> instance which is not “falsey” and so neither of the
+first two rules’ <code class="docutils literal notranslate"><span class="pre">if</span></code> clauses will ever be <code class="docutils literal notranslate"><span class="pre">True</span></code>. Later on I change
+the “truthiness” of <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> to false to let e.g.
+<code class="docutils literal notranslate"><span class="pre">joy.utils.stack.concat</span></code> work with our stack effect comment cons-list
+tuples.)</p>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
@@ -1509,13 +1483,13 @@ conversion function instead. This is programmer’s laziness.</p>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a0</span><span class="p">,</span> <span class="n">s0</span><span class="p">),</span> <span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">s0</span><span class="p">))))</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))))</span>
 </pre></div>
 </div>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">),</span> <span class="n">uncons</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s0</span><span class="p">)),</span> <span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s0</span><span class="p">))))))</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">))))))</span>
 </pre></div>
 </div>
 <p>The display function should be changed too.</p>
@@ -1575,7 +1549,7 @@ conversion function instead. This is programmer’s laziness.</p>
     <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ccons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a0</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ccons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 <span class="n">divmod_</span> <span class="o">=</span> <span class="p">(</span><span class="n">n2</span> <span class="n">n1</span> <span class="o">--</span> <span class="n">n4</span> <span class="n">n3</span><span class="p">)</span>
 <span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span>
@@ -1592,38 +1566,38 @@ conversion function instead. This is programmer’s laziness.</p>
 <span class="n">rest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a1</span><span class="p">)</span>
 <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
-<span class="n">rrest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
-<span class="n">second</span> <span class="o">=</span> <span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
-<span class="n">sqrt</span> <span class="o">=</span> <span class="p">(</span><span class="n">n0</span> <span class="o">--</span> <span class="n">n1</span><span class="p">)</span>
+<span class="n">rrest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
+<span class="n">second</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
+<span class="n">sqrt</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
 <span class="n">stack</span> <span class="o">=</span> <span class="p">(</span><span class="o">...</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
 <span class="n">succ</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
 <span class="n">swaack</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
 <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
-<span class="n">swons</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">a0</span> <span class="o">--</span> <span class="p">[</span><span class="n">a0</span> <span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
-<span class="n">third</span> <span class="o">=</span> <span class="p">([</span><span class="n">a0</span> <span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
+<span class="n">swons</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
+<span class="n">third</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a3</span><span class="p">)</span>
 <span class="n">tuck</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
 <span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack</span><span class="p">)</span>
 <span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
-<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">),</span> <span class="n">uncons</span><span class="p">))</span>
-<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">),</span> <span class="n">cons</span><span class="p">))</span>
+<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)))</span>
+<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)))</span>
 </pre></div>
 </div>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
 
-<span class="p">(</span><span class="o">...</span> <span class="n">a0</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a0</span> <span class="n">a0</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
+<span class="p">(</span><span class="o">...</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a1</span> <span class="n">a1</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
 
-<span class="p">(</span><span class="o">...</span> <span class="n">a1</span> <span class="n">a0</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a1</span> <span class="n">a0</span> <span class="n">a0</span> <span class="n">a1</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
+<span class="p">(</span><span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a1</span> <span class="n">a2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
 
-<span class="p">(</span><span class="o">...</span> <span class="n">a0</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a0</span> <span class="p">[</span><span class="n">a0</span> <span class="o">...</span><span class="p">])</span>
+<span class="p">(</span><span class="o">...</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a1</span> <span class="p">[</span><span class="n">a1</span> <span class="o">...</span><span class="p">])</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="n">a1</span> <span class="n">a0</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="n">a1</span> <span class="n">a0</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="p">[[</span><span class="n">a1</span> <span class="n">a0</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">...</span><span class="p">])</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">[[</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">...</span><span class="p">])</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Q</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
@@ -1631,7 +1605,7 @@ conversion function instead. This is programmer’s laziness.</p>
 <span class="n">Q</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">s0</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))),</span> <span class="p">(((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)),</span> <span class="n">s1</span><span class="p">),</span> <span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)),</span> <span class="n">s1</span><span class="p">)))</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s2</span><span class="p">))),</span> <span class="p">(((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">),</span> <span class="p">((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">)))</span>
 </pre></div>
 </div>
 <div class="section" id="compile-version-3">
@@ -1652,9 +1626,9 @@ comments are now already in the form needed for the Python code:</p>
 </pre></div>
 </div>
 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">Q</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
-    <span class="sd">&quot;&quot;&quot;(... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])&quot;&quot;&quot;</span>
-    <span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
-    <span class="k">return</span> <span class="p">(((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)),</span> <span class="n">s1</span><span class="p">),</span> <span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)),</span> <span class="n">s1</span><span class="p">))</span>
+    <span class="sd">&quot;&quot;&quot;(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])&quot;&quot;&quot;</span>
+    <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s2</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
+    <span class="k">return</span> <span class="p">(((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">),</span> <span class="p">((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">))</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">unstack</span> <span class="o">=</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
@@ -1676,19 +1650,19 @@ comments are now already in the form needed for the Python code:</p>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">))</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a0</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a0</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">enstacken</span><span class="p">))</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a0</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[[</span><span class="n">a0</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">s0</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">s0</span><span class="p">))</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span>
 </pre></div>
 </div>
 </div>
@@ -1730,8 +1704,8 @@ comments are now already in the form needed for the Python code:</p>
     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">dup</span><span class="p">),</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">),</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">e</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span> <span class="p">(</span><span class="n">i1</span> <span class="n">i2</span> <span class="o">--</span> <span class="n">i3</span><span class="p">)</span> <span class="p">(</span><span class="n">i0</span> <span class="o">--</span> <span class="n">i1</span><span class="p">)</span>
-<span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span> <span class="p">(</span><span class="n">f1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span> <span class="p">(</span><span class="n">f0</span> <span class="o">--</span> <span class="n">f1</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span> <span class="p">(</span><span class="n">i1</span> <span class="n">i2</span> <span class="o">--</span> <span class="n">i3</span><span class="p">)</span> <span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
+<span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span> <span class="p">(</span><span class="n">f1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span> <span class="p">(</span><span class="n">f1</span> <span class="o">--</span> <span class="n">f2</span><span class="p">)</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">product</span>
@@ -1749,19 +1723,19 @@ comments are now already in the form needed for the Python code:</p>
     <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">)))</span>
 </pre></div>
 </div>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">f0</span> <span class="o">--</span> <span class="n">f1</span><span class="p">)</span>
-<span class="p">(</span><span class="n">i0</span> <span class="o">--</span> <span class="n">i1</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">n0</span> <span class="o">--</span> <span class="n">n1</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">f1</span> <span class="o">--</span> <span class="n">f2</span><span class="p">)</span>
+<span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
 </pre></div>
 </div>
 <div class="section" id="representing-an-unbounded-sequence-of-types">
@@ -2024,23 +1998,23 @@ disappears:</p>
     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">f0</span> <span class="o">--</span> <span class="n">f1</span><span class="p">)</span>
-<span class="p">(</span><span class="n">i0</span> <span class="o">--</span> <span class="n">i1</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">f1</span> <span class="o">--</span> <span class="n">f2</span><span class="p">)</span>
+<span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n0</span><span class="o">*</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">n0</span><span class="o">*</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">n0</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">n1</span><span class="p">)</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">cons</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a0</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span>
-<span class="p">(</span><span class="n">n0</span> <span class="p">[</span><span class="n">n0</span><span class="o">*</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n1</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n1</span><span class="p">)</span>
+<span class="p">(</span><span class="n">n1</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">(((</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
@@ -2051,7 +2025,7 @@ disappears:</p>
     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">([</span><span class="n">n1</span> <span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span> <span class="p">(</span><span class="n">n0</span> <span class="p">[</span><span class="n">n0</span><span class="o">*</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n1</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">([</span><span class="n">n1</span> <span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span> <span class="p">(</span><span class="n">n1</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])))</span>
@@ -2241,70 +2215,77 @@ stack effect we have to “split universes” again and return both.</p>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">expression</span> <span class="o">=</span> <span class="n">l2s</span><span class="p">([</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">,</span> <span class="n">mul</span><span class="p">])</span>
 </pre></div>
 </div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">expression</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">n1</span><span class="p">,</span> <span class="p">(</span><span class="n">n2</span><span class="p">,</span> <span class="p">(</span><span class="n">mul</span><span class="p">,</span> <span class="p">())))</span>
+</pre></div>
+</div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">infer</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">f1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">i1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))]</span>
 </pre></div>
 </div>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">SymbolJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
-    <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;F&#39;</span>
-
-    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">stack_effects</span> <span class="o">=</span> <span class="n">sec</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
-
-<span class="k">class</span> <span class="nc">CombinatorJoyType</span><span class="p">(</span><span class="n">SymbolJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;C&#39;</span>
-
-<span class="k">def</span> <span class="nf">dip_t</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">):</span>
-    <span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
-    <span class="n">expression</span> <span class="o">=</span> <span class="n">stack_concat</span><span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">expression</span><span class="p">))</span>
-    <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span>
-
-<span class="n">CONS</span> <span class="o">=</span> <span class="n">SymbolJoyType</span><span class="p">(</span><span class="s1">&#39;cons&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">cons</span><span class="p">],</span> <span class="mi">23</span><span class="p">)</span>
-<span class="n">DIP</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">&#39;dip&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">dip_t</span><span class="p">],</span> <span class="mi">44</span><span class="p">)</span>
-
-
-<span class="k">def</span> <span class="nf">kav</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
-    <span class="c1">#i, stack = F</span>
-    <span class="k">if</span> <span class="ow">not</span> <span class="n">e</span><span class="p">:</span>
-        <span class="k">return</span> <span class="p">[(</span><span class="n">F</span><span class="p">,</span> <span class="n">e</span><span class="p">)]</span>
-    <span class="n">n</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">e</span>
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">SymbolJoyType</span><span class="p">):</span>
-        <span class="n">Fs</span> <span class="o">=</span> <span class="p">[]</span>
-        <span class="k">for</span> <span class="n">sec</span> <span class="ow">in</span> <span class="n">n</span><span class="o">.</span><span class="n">stack_effects</span><span class="p">:</span>
-            <span class="n">Fs</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">MC</span><span class="p">([</span><span class="n">F</span><span class="p">],</span> <span class="n">sec</span><span class="p">))</span>
-        <span class="k">return</span> <span class="p">[</span><span class="n">kav</span><span class="p">(</span><span class="n">Fn</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">Fn</span> <span class="ow">in</span> <span class="n">Fs</span><span class="p">]</span>
-    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">CombinatorJoyType</span><span class="p">):</span>
-        <span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
-        <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">n</span><span class="o">.</span><span class="n">stack_effects</span><span class="p">:</span>
-            <span class="n">s</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">e</span><span class="p">)</span>
-            <span class="n">new_F</span> <span class="o">=</span> <span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">s</span>
-            <span class="n">res</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">kav</span><span class="p">(</span><span class="n">new_F</span><span class="p">,</span> <span class="n">e</span><span class="p">))</span>
-        <span class="k">return</span> <span class="n">res</span>
-    <span class="n">lit</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
-    <span class="k">return</span> <span class="p">[</span><span class="n">kav</span><span class="p">(</span><span class="n">Fn</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">Fn</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">F</span><span class="p">],</span> <span class="p">[</span><span class="n">lit</span><span class="p">])]</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">infer</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">f1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">i1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))]</span>
+</pre></div>
+</div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="n">infer</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
+    <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">--</span> <span class="n">f1</span><span class="p">)</span>
+<span class="p">(</span><span class="o">--</span> <span class="n">i1</span><span class="p">)</span>
 </pre></div>
 </div>
-<p>compare, and be amazed:</p>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">dip_t</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">):</span>
-    <span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
-    <span class="n">expression</span> <span class="o">=</span> <span class="n">stack_concat</span><span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">expression</span><span class="p">))</span>
-    <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">expression</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">n1</span><span class="p">,</span> <span class="p">(</span><span class="n">n2</span><span class="p">,</span> <span class="p">(</span><span class="n">mul</span><span class="p">,</span> <span class="p">())))</span>
+</pre></div>
+</div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">infer</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
 </pre></div>
 </div>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">dip</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
-    <span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
-    <span class="n">expression</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
-    <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">f1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">i1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))]</span>
 </pre></div>
 </div>
 <p>And that brings us to current Work-In-Progress. I’m pretty hopeful that
-the mixed-mode inferencer/interpreter <code class="docutils literal notranslate"><span class="pre">kav()</span></code> function along with the
-ability to specify multiple implementations for the combinators will
+the mixed-mode inferencer/interpreter <code class="docutils literal notranslate"><span class="pre">infer()</span></code> function along with
+the ability to specify multiple implementations for the combinators will
 permit modelling of the stack effects of e.g. <code class="docutils literal notranslate"><span class="pre">ifte</span></code>. If I can keep up
 the pace I should be able to verify that conjecture by the end of June.</p>
+</div>
+<div class="section" id="conclusion">
+<h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this headline">¶</a></h2>
+<p>(for now…)</p>
+<p>Work remains to be done:</p>
+<ul class="simple">
+<li>the rest of the library has to be covered</li>
+<li>figure out how to deal with <code class="docutils literal notranslate"><span class="pre">loop</span></code> and <code class="docutils literal notranslate"><span class="pre">genrec</span></code>, etc..</li>
+<li>extend the types to check values (see the appendix)</li>
+<li>other kinds of “higher order” type variables, OR, AND, etc..</li>
+<li>maybe rewrite in Prolog for great good?</li>
+<li>definitions</li>
+<li>don’t permit composition of functions that don’t compose</li>
+<li>auto-compile compilable functions</li>
+<li>Compiling more than just the Yin functions.</li>
+<li>getting better visibility (than Python debugger.)</li>
+<li>DOOOOCS!!!! Lots of docs!</li>
+<li>docstrings all around</li>
+<li>improve this notebook (it kinda falls apart at the end narratively. I
+went off and just started writing code to see if it would work. It
+does, but now I have to come back and describe here what I did.</li>
+</ul>
+<p>I’m starting to realize that, with the inferencer/checker/compiler
+coming along, and with the UI ready to be rewritten in Joy, I’m close to
+a time when my ephasis is going to have to shift from crunchy code stuff
+to squishy human stuff. I’m going to have to put normal people in front
+of this and see if, in fact, they <em>can</em> learn the basics of programming
+with it.</p>
 <p>The rest of this stuff is junk and/or unfinished material.</p>
 </div>
 <div class="section" id="appendix-joy-in-the-logical-paradigm">
@@ -2312,134 +2293,104 @@ the pace I should be able to verify that conjecture by the end of June.</p>
 <p>For this to work the type label classes have to be modified to let
 <code class="docutils literal notranslate"><span class="pre">T</span> <span class="pre">&gt;=</span> <span class="pre">t</span></code> succeed, where e.g. <code class="docutils literal notranslate"><span class="pre">T</span></code> is <code class="docutils literal notranslate"><span class="pre">IntJoyType</span></code> and <code class="docutils literal notranslate"><span class="pre">t</span></code> is
 <code class="docutils literal notranslate"><span class="pre">int</span></code></p>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_ge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+    <span class="k">return</span> <span class="p">(</span><span class="nb">issubclass</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
+            <span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;accept&#39;</span><span class="p">)</span>
+            <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">accept</span><span class="p">))</span>
 
-<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
+<span class="n">AnyJoyType</span><span class="o">.</span><span class="fm">__ge__</span> <span class="o">=</span> <span class="n">_ge</span>
+<span class="n">AnyJoyType</span><span class="o">.</span><span class="n">accept</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="n">long</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="n">unicode</span><span class="p">,</span> <span class="nb">bool</span><span class="p">,</span> <span class="n">Symbol</span>
+<span class="n">StackJoyType</span><span class="o">.</span><span class="n">accept</span> <span class="o">=</span> <span class="nb">tuple</span>
 </pre></div>
 </div>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">---------------------------------------------------------------------------</span>
-
-<span class="ne">TypeError</span>                                 <span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">)</span>
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">119</span><span class="o">-</span><span class="mi">7</span><span class="n">fde90b4e88f</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span><span class="p">()</span>
-      <span class="mi">1</span> <span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
-      <span class="mi">2</span>
-<span class="o">----&gt;</span> <span class="mi">3</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">98</span><span class="o">-</span><span class="n">ddee30dbb1a6</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-     <span class="mi">10</span> <span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">11</span>     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-<span class="o">---&gt;</span> <span class="mi">12</span>     <span class="k">for</span> <span class="n">fg</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">13</span>         <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">l2s</span><span class="p">((</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)))</span>
 
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">97</span><span class="o">-</span><span class="mi">5</span><span class="n">eb7ac5ad2c2</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-      <span class="mi">1</span> <span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-<span class="o">----&gt;</span> <span class="mi">2</span>     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
-      <span class="mi">3</span>     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
-      <span class="mi">4</span>     <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
-      <span class="mi">5</span>         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">98</span><span class="o">-</span><span class="n">ddee30dbb1a6</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-     <span class="mi">10</span> <span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">11</span>     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-<span class="o">---&gt;</span> <span class="mi">12</span>     <span class="k">for</span> <span class="n">fg</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">13</span>         <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">97</span><span class="o">-</span><span class="mi">5</span><span class="n">eb7ac5ad2c2</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-      <span class="mi">1</span> <span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-<span class="o">----&gt;</span> <span class="mi">2</span>     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
-      <span class="mi">3</span>     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
-      <span class="mi">4</span>     <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
-      <span class="mi">5</span>         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">98</span><span class="o">-</span><span class="n">ddee30dbb1a6</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-     <span class="mi">10</span> <span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">11</span>     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-<span class="o">---&gt;</span> <span class="mi">12</span>     <span class="k">for</span> <span class="n">fg</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">13</span>         <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">97</span><span class="o">-</span><span class="mi">5</span><span class="n">eb7ac5ad2c2</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-      <span class="mi">1</span> <span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-<span class="o">----&gt;</span> <span class="mi">2</span>     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
-      <span class="mi">3</span>     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
-      <span class="mi">4</span>     <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
-      <span class="mi">5</span>         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">98</span><span class="o">-</span><span class="n">ddee30dbb1a6</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-     <span class="mi">10</span> <span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">11</span>     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-<span class="o">---&gt;</span> <span class="mi">12</span>     <span class="k">for</span> <span class="n">fg</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">13</span>         <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">97</span><span class="o">-</span><span class="mi">5</span><span class="n">eb7ac5ad2c2</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-      <span class="mi">1</span> <span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-<span class="o">----&gt;</span> <span class="mi">2</span>     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
-      <span class="mi">3</span>     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
-      <span class="mi">4</span>     <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
-      <span class="mi">5</span>         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">98</span><span class="o">-</span><span class="n">ddee30dbb1a6</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-     <span class="mi">10</span> <span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">11</span>     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-<span class="o">---&gt;</span> <span class="mi">12</span>     <span class="k">for</span> <span class="n">fg</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">13</span>         <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">97</span><span class="o">-</span><span class="mi">5</span><span class="n">eb7ac5ad2c2</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-      <span class="mi">1</span> <span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-<span class="o">----&gt;</span> <span class="mi">2</span>     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
-      <span class="mi">3</span>     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
-      <span class="mi">4</span>     <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
-      <span class="mi">5</span>         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">98</span><span class="o">-</span><span class="n">ddee30dbb1a6</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-     <span class="mi">10</span> <span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">11</span>     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-<span class="o">---&gt;</span> <span class="mi">12</span>     <span class="k">for</span> <span class="n">fg</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-     <span class="mi">13</span>         <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
-
-
-<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">97</span><span class="o">-</span><span class="mi">5</span><span class="n">eb7ac5ad2c2</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
-      <span class="mi">1</span> <span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
-<span class="o">----&gt;</span> <span class="mi">2</span>     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
-      <span class="mi">3</span>     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
-      <span class="mi">4</span>     <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
-      <span class="mi">5</span>         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
-
-
-<span class="ne">TypeError</span><span class="p">:</span> <span class="s1">&#39;SymbolJoyType&#39;</span> <span class="nb">object</span> <span class="ow">is</span> <span class="ow">not</span> <span class="n">iterable</span>
+<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">F</span><span class="p">:</span>
+    <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a4</span> <span class="n">a5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.parser</span> <span class="k">import</span> <span class="n">text_to_expression</span>
 </pre></div>
 </div>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;[3 4 ...] 2 1&#39;</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">l2s</span><span class="p">((</span><span class="n">pop</span><span class="p">,</span> <span class="n">pop</span><span class="p">,</span> <span class="n">pop</span><span class="p">)))</span>
+
+<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">F</span><span class="p">:</span>
+    <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
+</pre></div>
+</div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;0 1 2&#39;</span><span class="p">)</span>
 <span class="n">s</span>
 </pre></div>
 </div>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">s</span><span class="p">)</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">())))</span>
+</pre></div>
+</div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)))</span>
+</pre></div>
+</div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
 <span class="n">L</span>
 </pre></div>
 </div>
-<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">()</span>
+</pre></div>
+</div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;0 1 2 [3 4]&#39;</span><span class="p">)</span>
+<span class="n">s</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="p">())),</span> <span class="p">()))))</span>
+</pre></div>
+</div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)))</span>
+</pre></div>
+</div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
+<span class="n">L</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">()</span>
+</pre></div>
+</div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">s</span><span class="p">)</span>
+<span class="n">L</span>
+</pre></div>
+</div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">()</span>
 </pre></div>
 </div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
 </pre></div>
 </div>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">---------------------------------------------------------------------------</span>
+
+<span class="ne">IndexError</span>                                <span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">)</span>
+
+<span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">133</span><span class="o">-</span><span class="mi">58</span><span class="n">a8e44e9cba</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span><span class="p">()</span>
+<span class="o">----&gt;</span> <span class="mi">1</span> <span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
+
+
+<span class="ne">IndexError</span><span class="p">:</span> <span class="nb">list</span> <span class="n">index</span> <span class="n">out</span> <span class="n">of</span> <span class="nb">range</span>
+</pre></div>
+</div>
 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">s</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
 </pre></div>
 </div>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="mi">23</span>
+</pre></div>
+</div>
 </div>
 <div class="section" id="abstract-interpretation">
 <h2><a class="reference external" href="https://en.wikipedia.org/wiki/Abstract_interpretation">Abstract Interpretation</a><a class="headerlink" href="#abstract-interpretation" title="Permalink to this headline">¶</a></h2>
@@ -2637,7 +2588,7 @@ how much information we <em>could</em> retain:</p>
 <li><a class="reference internal" href="#pop-swap"><code class="docutils literal notranslate"><span class="pre">pop</span> <span class="pre">swap</span></code></a></li>
 <li><a class="reference internal" href="#popswap-roll"><code class="docutils literal notranslate"><span class="pre">pop∘swap</span> <span class="pre">roll&lt;</span></code></a></li>
 <li><a class="reference internal" href="#compiling-popswaproll">Compiling <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;</span></code></a></li>
-<li><a class="reference internal" href="#functions-on-lists">Functions on Lists</a></li>
+<li><a class="reference internal" href="#functions-on-stacks">Functions on Stacks</a></li>
 <li><a class="reference internal" href="#popswaproll-rest"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;</span> <span class="pre">rest</span></code></a></li>
 <li><a class="reference internal" href="#popswaproll-rest-rest"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest</span> <span class="pre">rest</span></code></a></li>
 <li><a class="reference internal" href="#popswaproll-restrest-cons"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest∘rest</span> <span class="pre">cons</span></code></a></li>
@@ -2702,6 +2653,7 @@ how much information we <em>could</em> retain:</p>
 </ul>
 </li>
 <li><a class="reference internal" href="#part-vii-typing-combinators">Part VII: Typing Combinators</a></li>
+<li><a class="reference internal" href="#conclusion">Conclusion</a></li>
 <li><a class="reference internal" href="#appendix-joy-in-the-logical-paradigm">Appendix: Joy in the Logical Paradigm</a></li>
 <li><a class="reference internal" href="#abstract-interpretation">Abstract Interpretation</a></li>
 <li><a class="reference internal" href="#junk">Junk</a><ul>
index 6176ea2..937acd7 100644 (file)
 <li class="toctree-l2"><a class="reference internal" href="Types.html#part-v-functions-that-use-the-stack">Part V: Functions that use the Stack</a></li>
 <li class="toctree-l2"><a class="reference internal" href="Types.html#part-vi-multiple-stack-effects">Part VI: Multiple Stack Effects</a></li>
 <li class="toctree-l2"><a class="reference internal" href="Types.html#part-vii-typing-combinators">Part VII: Typing Combinators</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Types.html#conclusion">Conclusion</a></li>
 <li class="toctree-l2"><a class="reference internal" href="Types.html#appendix-joy-in-the-logical-paradigm">Appendix: Joy in the Logical Paradigm</a></li>
 <li class="toctree-l2"><a class="reference internal" href="Types.html#abstract-interpretation">Abstract Interpretation</a></li>
 <li class="toctree-l2"><a class="reference internal" href="Types.html#junk">Junk</a></li>
index 3f8d770..4cb8576 100644 (file)
@@ -1 +1 @@
-Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Recursion_Combinators","notebooks/Replacing","notebooks/Treestep","notebooks/Types","notebooks/Zipper","notebooks/index","parser","pretty","stack"],envversion:52,filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Recursion_Combinators.rst","notebooks/Replacing.rst","notebooks/Treestep.rst","notebooks/Types.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst"],objects:{"joy.joy":{joy:[1,1,1,""],repl:[1,1,1,""],run:[1,1,1,""]},"joy.library":{"void":[3,1,1,""],BinaryBuiltinWrapper:[3,1,1,""],DefinitionWrapper:[3,2,1,""],FunctionWrapper:[3,1,1,""],SimpleFunctionWrapper:[3,1,1,""],UnaryBuiltinWrapper:[3,1,1,""],add_aliases:[3,1,1,""],app1:[3,1,1,""],app2:[3,1,1,""],app3:[3,1,1,""],b:[3,1,1,""],branch:[3,1,1,""],choice:[3,1,1,""],clear:[3,1,1,""],cmp_:[3,1,1,""],concat_:[3,1,1,""],cond:[3,1,1,""],dip:[3,1,1,""],dipd:[3,1,1,""],dipdd:[3,1,1,""],divmod_:[3,1,1,""],drop:[3,1,1,""],dupdip:[3,1,1,""],floor:[3,1,1,""],genrec:[3,1,1,""],getitem:[3,1,1,""],help_:[3,1,1,""],i:[3,1,1,""],id_:[3,1,1,""],ifte:[3,1,1,""],infra:[3,1,1,""],initialize:[3,1,1,""],inscribe:[3,1,1,""],loop:[3,1,1,""],map_:[3,1,1,""],max_:[3,1,1,""],min_:[3,1,1,""],parse:[3,1,1,""],pm:[3,1,1,""],pred:[3,1,1,""],remove:[3,1,1,""],reverse:[3,1,1,""],select:[3,1,1,""],sharing:[3,1,1,""],shunt:[3,1,1,""],sort_:[3,1,1,""],sqrt:[3,1,1,""],step:[3,1,1,""],succ:[3,1,1,""],sum_:[3,1,1,""],swaack:[3,1,1,""],take:[3,1,1,""],times:[3,1,1,""],unique:[3,1,1,""],unstack:[3,1,1,""],warranty:[3,1,1,""],words:[3,1,1,""],x:[3,1,1,""],zip_:[3,1,1,""]},"joy.library.DefinitionWrapper":{add_def:[3,3,1,""],add_definitions:[3,3,1,""],parse_definition:[3,3,1,""]},"joy.parser":{ParseError:[18,4,1,""],Symbol:[18,2,1,""],text_to_expression:[18,1,1,""]},"joy.utils":{generated_library:[3,0,0,"-"],pretty_print:[19,0,0,"-"],stack:[20,0,0,"-"]},"joy.utils.generated_library":{ccons:[3,1,1,""],cons:[3,1,1,""],dup:[3,1,1,""],dupd:[3,1,1,""],dupdd:[3,1,1,""],first:[3,1,1,""],first_two:[3,1,1,""],fourth:[3,1,1,""],over:[3,1,1,""],pop:[3,1,1,""],popd:[3,1,1,""],popdd:[3,1,1,""],popop:[3,1,1,""],popopd:[3,1,1,""],popopdd:[3,1,1,""],rest:[3,1,1,""],rolldown:[3,1,1,""],rollup:[3,1,1,""],rrest:[3,1,1,""],second:[3,1,1,""],stack:[3,1,1,""],stuncons:[3,1,1,""],stununcons:[3,1,1,""],swap:[3,1,1,""],swons:[3,1,1,""],third:[3,1,1,""],tuck:[3,1,1,""],uncons:[3,1,1,""],unswons:[3,1,1,""]},"joy.utils.pretty_print":{TracePrinter:[19,2,1,""]},"joy.utils.pretty_print.TracePrinter":{go:[19,5,1,""],viewer:[19,5,1,""]},"joy.utils.stack":{concat:[20,1,1,""],expression_to_string:[20,1,1,""],iter_stack:[20,1,1,""],list_to_stack:[20,1,1,""],pick:[20,1,1,""],stack_to_string:[20,1,1,""]},joy:{joy:[1,0,0,"-"],library:[3,0,0,"-"],parser:[18,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","classmethod","Python class method"],"4":["py","exception","Python exception"],"5":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:classmethod","4":"py:exception","5":"py:method"},terms:{"0b11100111011011":5,"23rd":15,"4b4cb6ff86e5":[],"5bkei":10,"5eb7ac5ad2c2":15,"7fde90b4e88f":15,"\u03b5":8,"abstract":[7,10,17],"boolean":[2,3,7,10],"break":[7,15],"byte":5,"case":[2,3,12,14,15,20],"class":[3,7,15,18,19,20],"default":[3,6,10,20],"export":[3,18],"final":[2,10,12],"float":[3,7,15,16,18],"function":[0,1,4,5,6,9,11,16,17,18,19,20],"g\u00e9rard":16,"import":[2,5,6,8,10,11,12,13,14,15,16],"int":[6,7,12,15,16,18,20],"long":[10,17],"new":[2,3,6,7,9,12,13,15],"p\u00f6ial":17,"p\u00f6ial06typingtool":15,"public":9,"return":[1,3,5,7,10,12,13,14,15,18,19,20],"static":[2,9],"super":15,"switch":[2,15],"throw":10,"true":[2,3,5,12,15],"try":[6,8,11,12,14,15],"void":[0,3],"while":[3,7,10,15,18,20],Adding:[7,13,17],And:[5,6,8,10,12,15,16,20],But:[0,4,5,6,7,10,13,15],CPS:7,FNs:15,For:[2,3,10,12,13,15,17,20],Has:3,Its:3,One:[2,7,15,17],TOS:[2,3],That:[5,10],The:[0,1,2,3,4,6,8,9,11,15,16,17,18,20],Then:[2,3,10,11,12,15],There:[11,12,14,15,20],These:[15,17,20],Use:[3,8,12],Using:[0,8,10,17],With:[8,12,15,17],_1000:15,__add__:15,__class__:15,__eq__:15,__ge__:15,__hash__:15,__init__:15,__main__:15,__name__:15,__radd__:15,__repr__:15,__str__:19,_names_for:15,_to_str:15,_tree_add_:10,_tree_add_e:10,_tree_add_p:10,_tree_add_r:10,_tree_add_t:10,_tree_delete_:10,_tree_delete_clear_stuff:10,_tree_delete_del:10,_tree_delete_r0:10,_tree_delete_r1:10,_tree_delete_rightmost:10,_tree_delete_w:10,_tree_get_:10,_tree_get_p:10,_tree_get_r:10,_tree_get_t:10,_tree_iter_order_curr:10,_tree_iter_order_left:10,_tree_iter_order_r:10,_tree_iter_order_right:10,_tree_t:10,_treestep_0:14,_treestep_1:14,_uniqu:15,_within_b:8,_within_p:8,_within_r:8,a10001:15,a10002:15,a10003:15,a10004:15,a1001:[],abbrevi:14,abil:15,abl:15,about:[0,7,10,15,16,20],abov:[0,5,8,10,12,15],abs:8,absolut:7,accept:[1,2,3,5,6,7,10,11,13,14,15,16],accordingli:10,accumul:5,action:[7,13,15,16],actual:[2,5,7,10,15],adapt:17,add:[3,5,6,7,13,15,19],add_alias:3,add_def:3,add_definit:[3,10,14],added:[4,10],adding:[9,15],addit:[0,2,3,5,7,12,13,14],address:17,adjust:10,after:[5,6,7,12],afterward:7,again:[2,3,5,7,10,12,15],aggreg:16,ahead:15,aka:[7,16],albrecht:0,algorithm:[7,15],alia:3,alias:[3,7],align:[7,19],all:[3,5,6,7,10,12,13,14,15,19],alloc:15,allow:[9,10],almost:10,along:[7,12,15],alphabet:3,alreadi:[8,13,15,16],also:[0,5,7,10,15,20],alter:15,altern:[4,15],although:[4,10,15],altogeth:6,alwai:[5,9,12],amaz:15,among:15,amort:10,analysi:[4,17],anamorph:[7,17],ani:[4,5,7,9,10,15,16,18],annual:7,anonym:10,anoth:[10,15,20],anyhow:15,anyjoytyp:15,anymor:15,anystarjoytyp:15,anyth:[2,3,7,15],api:9,app1:3,app2:[3,7,11,12,13],app3:3,app:7,appear:[2,4,5,10],append:15,appendix:17,appli:[2,3,5,6,10,12,15],applic:6,approach:5,approxim:17,archiv:0,aren:16,arg:[2,3],argument:[2,3,7,8,11,12,17,19,20],arithmet:2,ariti:2,around:[5,15,20],arrang:14,arriv:[6,14],articl:[0,4,6,12],ask:[4,6,15],aspect:0,assert:15,assign:20,associ:10,assum:8,astar:15,asterisk:14,asterix:15,attack:7,attempt:[0,1],attribut:3,attributeerror:15,author:15,auto:0,automat:[4,15],auxiliari:14,avail:[0,15],averag:[7,13],avoid:10,awai:10,awar:2,awkward:[10,12],azur:17,back:[10,15],backward:[9,10,11,14],bag:7,banana:12,barb:12,base:[0,2,3,9,12,14,15],basic:[1,2,3,7,10],becaus:[2,3,7,10,14,15,16,20],becom:[10,14,20],becuas:15,been:[8,9,10,15,16],befor:[6,7,10],begin:[10,14],behavior:[9,14],behaviour:[0,1,15],being:0,below:[2,3,5,6,10,15,16],bespok:7,best:0,better:[5,10,12],between:[0,5],beyond:6,biannual:7,binari:[0,6,7,17],binary_search_tre:10,binarybuiltinwrapp:3,bind:7,bingo:16,bit:[5,6,10,15],block:5,bodi:[2,7,10],body_text:3,booktitl:15,bool:12,borrow:[7,15],both:[2,5,7,11,12,13,15,20],bottom:6,bracket:[7,15,18],branch:[3,5,6,12,15],branch_fals:15,branch_tru:15,breakpoint:7,bring:[5,7,15],bruijn:15,brzozowski:15,btree:[10,14],buck:10,bug:[0,7],build:[6,7,11,12,15,16,20],built:[11,15],bundl:[2,3,12],burgeon:7,calculu:4,call:[2,7,9,10,12,15,19,20],caller:10,can:[0,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,20],cannot:15,captur:7,card:7,care:[5,20],carefulli:16,carri:[6,10],cartesian:4,catamorph:17,categor:[0,17],categori:4,ccc:4,ccon:[3,10,15],cell:[12,15],certain:[7,20],certainli:10,chain:[3,15],chang:[2,9,10,15,16],charact:16,chat:7,chatter:[0,15],check:[6,8,15],child:14,choic:[3,12],choos:9,chop:11,cinf:10,circuit:4,cite_not:10,classmethod:3,claus:[3,15],clean:15,clear:[3,5,7],clear_stuff:10,cleav:[7,11,13],close:[0,1,4],clunki:[5,15],cmp:[3,14,17],cmp_:3,code:[0,1,4,11,12,15,17],codireco:[6,8],collaps:12,collect:[4,6,7,15],combin:[0,3,5,6,7,8,11,14,16,17],combinatorjoytyp:15,combo:15,come:[7,10,15],command:[7,10,15],common:[2,5],compar:[3,4,15],comparison:[0,10],compel:4,compil:[2,4,7,10,13,17],complet:[4,15],complex:[3,15,16],complic:15,composit:15,compostit:15,compound:10,comput:[2,4,5,7,11,15],con:[3,5,6,7,8,10,11,12,14,16,20],conal:4,concat:[3,6,7,14,20],concat_:3,concaten:0,concatin:[0,3,20],conclus:17,concurr:2,cond:[3,10],condit:[3,7],confer:15,conflict:[10,15],conjectur:15,consecut:17,consid:[5,6,10,12,14,15,16],consist:[2,6,7,14],constant:10,constitu:12,constraint:15,construct:15,consum:15,contain:[0,2,3,6,7,12,15],content:15,context:2,conting:10,continu:[0,12,15,16],control:7,conveni:[4,15],convers:15,convert:[12,13,14,15,18,20],cool:10,copi:[2,3,5,10,12,14,17],copyright:7,correct:15,correspond:4,could:[2,4,5,7,9,10,15,16],count:[3,15],counter:[5,15],coupl:14,cours:[5,10,15],cover:15,crack:10,crap:15,crash:10,creat:[0,2,3,5,8,10,15],creativ:15,crude:[10,15,18],currect:[],current:[2,3,7,12,14,15,16,19],custom:9,cycl:[5,6],cython:7,dai:7,data:[2,3,12],datastructur:[0,2,12,15,17,18,20],datatyp:20,ddee30dbb1a6:15,ddididi:16,deal:[0,10],dealt:15,decid:10,declar:15,decor:3,decoupl:12,decrement:3,deduc:[5,15],deeper:0,deepli:4,def:[3,7,12,13,15,20],defaultdict:15,defi:3,defin:[2,3,4,5,6,7,8,9,11,12,13,15,16,17],definit:[2,3,5,6,7,9,10,12,14,15,17],definitionwrapp:[3,10,12,14],deleg:7,delet:17,deliber:15,demonstr:4,depend:[3,10,12],deposit:14,depth:15,dequot:12,der:10,deriv:[2,3,5,7,8,10,15,17],describ:[3,4,10,12,14,15,18],descript:[5,7],descriptor:15,design:[2,3,10,17],desir:[7,14],destruct:10,detail:[7,10,15],detect:[6,10,12,15],determin:17,develop:[0,6,7,15,17],diagram:5,dialect:1,dict:[1,3,15],dictionari:[0,1,3,7,15,17],differ:[0,4,5,8,10,11,12,20],differenti:4,difficult:15,dig:[10,16],digit:5,dinfrirst:7,dip:[3,5,6,7,8,10,11,12,13,14,15,17],dip_a:15,dip_t:15,dipd:[3,6,7,10,11,12,15,16],dipdd:[3,10,15],direco:17,direct:7,directli:[5,14,15,20],disappear:[2,15],discard:[3,6,8,10,12],disciplin:10,disenstacken:7,disk:7,displac:2,displai:15,distiguish:15,ditch:10,div:[3,7],dive:14,divis:10,divmod:3,divmod_:[3,15],doc:[2,3,7,15],document:[17,18,20],doe:[0,1,4,6,7,13,17,19],doesn:[5,9,10,14,15,20],doing:[4,5,7,15,16],domain:[4,15],don:[5,7,10,15],done:[2,5,7,9,15],door:7,dot:19,doubl:[5,7,15],down:[2,8,12,15,16],down_to_zero:7,dozen:7,draft:[4,9],dream:7,drive:[6,8],driven:5,driver:6,drop:[3,10],dudipd:7,due:15,dup:[3,5,6,7,8,10,11,12,16,20],dupd:[3,15],dupdd:3,dupdip:[3,5,10,11,12,15],duplic:[3,10,12],durat:2,dure:[2,12],each:[2,3,4,5,7,12,13,14,15,19],easi:[0,10,14,15,16],easier:[3,10],easili:4,edit:17,effect:[2,3,7,16,17],effici:[6,13,16],either:[1,2,3,10,12,15],elabor:15,eleg:[7,10,15],element:2,elif:15,elimin:15,elliott:4,els:[2,3,12,15],else_:15,embed:[4,10,16],emit:15,empti:[3,7,14,15,20],encapsul:7,enclos:7,encod:6,encount:15,end:[5,10,12,14,15,20],endless:6,enforc:[2,7],engend:7,enorm:15,enough:[7,12,15,19],enstacken:[6,7,15],enter:7,entir:20,entri:[3,16,19],enumer:15,epsilon:8,equal:[5,14,20],equat:[7,8],ergo:10,err:10,error:[7,18],essai:0,establish:15,etc:[3,14,15,16,18],euler:17,euro:15,eval:[0,15],evalu:[1,2,3,7,8,10,11,12,13,14,15],event:15,eventu:15,everi:[6,15],everyth:[3,10,11,15],evolv:9,examin:12,exampl:[0,3,5,15,17,18,20],exce:6,except:[7,10,15,18],execut:[0,1,2,3,7,12,13,14,15,16,20],exend:15,exercis:10,exist:[4,10,15],expand:10,expect:[2,3,14,15,20],experi:[7,14],explain:15,explan:7,explor:7,express:[0,1,2,3,4,10,12,13,15,16,19,20],expression_to_str:20,extend:15,extra:[5,6],extract:[10,11,17],extrem:7,extrememli:7,f1001:[],f_g:15,f_in:15,f_out:15,f_python:15,facet:0,facil:7,fact:18,factor:[2,5,7,10,15],factori:17,fail:[2,3,10,18],fairli:15,fale:[],fals:[2,3,5,12,15],far:[8,10,12,15],fascin:0,fear:[10,15],few:[5,7,8,11],fewer:[3,7],fg_in:15,fg_out:15,fib:6,fib_gen:6,fibonacci:17,figur:[2,3,10,12],filter:10,fin:5,find:[2,3,5,6,14,15,17],finder:8,fine:[0,5,10,15],first:[3,6,7,8,10,11,12,13,14,16,17],first_two:[3,10],fit:[5,7],five:[5,7,17],fix:[2,3,12,15],fixm:[],flag:15,flatten:[7,14,15],flexibl:17,floatjoytyp:15,floatstarjoytyp:15,floor:3,floordiv:5,flow:7,follow:[0,2,3,7,9,12,14,15,16],foo:[7,9,10,15],foo_ii:9,form:[2,3,4,5,6,12,14,15,20],forman:7,format:[15,17,19],formula:[0,5,17],forth:[7,15],forum:0,forward:15,found:7,foundat:15,four:[2,3,5,6,7,10,17],fourteen:5,fourth:[2,3,10,12],fractal:7,fraction0:7,fraction:[2,7],frame:12,framework:7,free:[4,7,10],freeli:2,from:[0,1,2,3,5,6,7,8,10,11,12,13,14,15,16,17,20],from_iter:15,front:[2,3,12],full:5,fulli:15,fun:17,func:15,functionjoytyp:15,functionwrapp:3,funtion:10,further:[8,15,17],g_in:15,g_out:15,garbag:7,gari:10,gcd:7,gener:[0,2,4,12,15,17,20],generated_librari:3,genrec:[3,7,10,12,14],geometr:5,get:[2,4,5,6,7,11,12,15,17],getitem:3,getrecursionlimit:20,getsourc:7,ghc:4,give:[4,5,10,12,14,15,20],given:[2,3,5,6,8,10,12,15,16,17],global:15,glue:7,going:[10,11,14,15,16],good:[5,10],grab:[3,15],grammar:18,grand:7,great:[0,7,15,17],greater:20,grok:15,group:0,gsra:8,guard:10,had:[5,15,16],haiku:7,half:[5,15,16],hand:[7,13,15,17],handi:[8,15],handl:[10,15,20],happen:[7,15],hard:[15,16],hardwar:4,has:[0,2,6,7,8,9,10,12,15,16,20],hash:15,haskel:4,have:[2,3,5,6,7,8,9,12,13,15,16,17,20],haven:15,head:20,help:[7,10,12,15],help_:3,helper:3,herd:7,here:[5,6,10,14,15,16],hide:10,hierarchi:15,higher:[7,10],highli:7,histori:[15,19],hmm:10,hoist:3,hold:[5,15],hood:10,hope:[0,5,7,15,17],hopefulli:12,host:17,how:[0,4,8,10,12,15,16,17],howev:[12,13,15],html:[2,3,6,11,12,17],http:10,huet:16,huge:10,hugh:[8,14],human:7,hybrid:15,hylomorph:17,hypothet:2,id_:3,idea:[4,5,7,15],ident:[3,12,15],if_not_empti:10,ift:[3,10,12,14,15],ignor:[3,10,15],iii:17,illustr:12,imagin:16,imap:15,imit:14,immedi:12,immut:[7,10],imper:12,implement:[0,1,2,3,4,7,9,10,12,13,17],impli:15,implicit:7,includ:[4,10,14,15],inclus:5,incom:20,incompat:9,incorpor:11,increas:5,increment:[3,4,5,9],index:[0,7,15,20],indexerror:20,indic:[14,15],ineffici:15,infer:[0,17],inform:[3,15],infra:[3,6,7,10,11,13,14,15,17],infrastructur:3,initi:[2,3,7,8,10],inlin:10,inner:15,inproceed:15,input:[1,8,15],inscrib:3,insert:15,insight:12,inspect:7,instal:0,instanti:[4,19],instead:[5,6,10,12,15,16,20],integ:[2,3,7,12,14,15],integr:3,intend:[0,7],interact:[7,17],interest:[0,5,10,15,17],interlud:17,intermedi:12,intern:[0,15,19,20],interpret:[0,4,9,13,17,18,19],interrupt:7,interv:[4,5],intjoytyp:15,introduc:9,introduct:0,intstarjoytyp:15,intuit:15,invari:3,invent:15,involv:15,ipf:7,ipython:15,isinst:15,isn:[10,16],issubclass:15,item:[2,3,7,10,12,14,15,17,20],iter:[1,3,7,12,14,15,17,20],iter_stack:[13,15,20],iteritem:15,itertool:15,its:[0,2,3,4,5,7,10,12,14,15,20],itself:[0,2,7,10,15],j05cmp:[2,3,12],jaanu:15,job:17,john:[8,14],joi:[2,4,9,10,11,13],join:15,joypi:[7,16],june:15,junk:17,jupyt:17,just:[0,2,3,6,7,9,10,12,14,15,16],kav:15,keep:[10,11,15,16],kei:[14,17],kevin:0,key_n:10,keyerror:[10,15],kind:[2,4,7,10,12,14,15],kinda:15,kjs:15,kleen:[14,15],kleenestar:15,kleffner:15,know:[5,10,15],knowledg:15,known:4,l2s:15,l_kei:10,l_left:10,l_right:10,l_valu:10,label:15,lambda:[4,15],languag:[4,7,9,10,13,15],larg:15,larger:20,largest:3,last:[5,10,12,15],lastli:6,later:[7,14,15],law:[2,15],lazi:15,lazili:8,lcm:5,lead:[7,15],leaf:10,lean:7,learn:0,least:[2,5,12,15,20],least_fract:7,leav:5,left:[7,11,12,14,15,16,19,20],leftov:12,len:15,length:[3,5,20],lens:12,less:[5,6,7,12,15,20],let:[6,8,10,11,12,14,15,16],letter:15,level:[4,10],librari:[0,13],like:[2,3,5,7,14,15,17,18],limit:15,line:[3,7,10,11,19],linear:20,link:0,linux:0,list:[0,3,5,7,8,10,12,14,16,19],list_to_stack:[15,20],lit:15,liter:[1,10,14,15,16,18],literatur:15,littl:[6,10,15,17],live:17,lkei:14,load:[5,7],local:15,locat:2,locu:19,lof:15,log_2:10,logic:[0,5,17],longer:[10,15],look:[6,7,8,10,11,15],lookup:7,loop:[0,1,3,5],lose:15,lot:[7,10,16],love:5,low:4,lower:5,lowercas:15,lowest:10,machin:0,machineri:[10,15],macro:7,made:[0,7,15,16],magic:15,mai:[2,12,15],mail:0,main:[0,3,7,11,15,16],mainloop:9,maintain:16,major:9,make:[2,3,4,5,7,10,12,13,14,15,16,17],make_gener:8,manfr:[0,2,3,4,12],mani:[0,7,15],manipul:15,manner:11,map:[1,3,5,7,9,12,14,15],map_:3,marker:7,mask:[5,6],match:[0,1],materi:[0,15],math:[0,7,8,10,11,15],mathemat:7,matter:[5,8,10,14],max_:3,maximum:3,mayb:10,mean:[4,5,7,8,10,12,14,15,20],meant:[7,10,12,14],member:[2,3,12],mental:[7,15],mention:2,mercuri:0,mess:15,meta:[7,10,13],meta_compos:15,metal:15,method:[0,3,7,15,17,19],midpoint:5,might:[4,6,10,15],mike:10,million:6,min_:3,mind:15,minimum:3,minor:10,minu:3,mirror:0,miscellan:0,mix:[7,15],mod:3,mode:15,model:[4,7,15],modern:0,modif:6,modifi:[7,10,16],modul:[0,1,3,7,15,18],modulu:7,moment:15,month:7,more:[0,3,4,5,6,7,8,12,13,14,15,18,20],most:15,mostli:0,motiv:15,move:10,movement:2,much:[5,6,10,12,15],muck:10,mul:[7,11,16,19],multi:3,multipl:17,must:[2,3,5,9,12,14,15],myself:15,n10001:15,n10002:15,n10003:15,n1001:15,n1002:15,n1003:15,name:[1,3,7,9,10,12,15,16,17,18,20],natur:[5,6,10],navig:16,nearli:15,neat:10,neato:15,necessarili:15,need:[2,3,5,6,8,9,10,12,15],neg:[3,11],nest:[3,7,10,16],network:7,never:[9,12],new_def:15,new_f:15,new_fo:15,new_kei:10,new_valu:10,newton:[0,17],next:[5,14,15],nice:[0,12,20],niether:2,node:[14,17],node_kei:10,node_valu:10,non:[14,15],none:[1,3,15],nope:14,notat:[7,10],note:[2,5,8,10,12,15,20],notebook:[5,6,7,15,16,17],notebook_preambl:[2,5,6,8,10,11,12,13,14,15,16],noth:[2,10],notic:5,now:[5,6,7,12,13,14,15,17],nth:[3,20],nullari:[7,10],number:[1,2,3,5,6,8,20],numberjoytyp:15,numberstarjoytyp:15,numer:15,object:[15,18],observ:5,obviou:6,obvious:15,occur:10,odd:[5,6],off:[2,3,5,6,11,16],okai:[],old:[2,13],old_k:10,old_kei:10,old_valu:10,omit:[12,15],onc:[3,9,10],one:[2,3,5,6,10,12,14,15,19,20],ones:[6,15],onli:[2,3,5,10,12,15,16,20],onto:[1,2,3,7,12,20],open:[7,15],oper:[3,7,10,12,15,20],oppos:15,optim:10,option:[1,7,10,20],order:[0,2,3,7,12,15,17,20],org:[0,10],origin:[0,1,2,3,10,15,16],other:[0,2,3,4,7,10,12,14,15,20],otherwis:[3,5,6,10,14,15],our:[5,6,7,8,12,14,15],out:[2,3,4,5,6,7,8,10,11,12,15,16],outcom:14,output:[8,12,15],outsid:4,over:[3,4,5,6,7,8,10,11,14,15,17],overhaul:15,overview:15,own:[10,15],pace:15,pack:20,packag:[0,7],page:[0,10,15,20],pair:[2,3,5,6,10,15],palidrom:5,palindrom:5,pam:7,paper:[4,7,12,16],paradigm:17,parallel:2,paramet:[1,2,3,12,13,18,19,20],parameter:17,paramorph:12,parenthes:[10,20],pariti:6,pars:[0,3,7],parse_definit:3,parseerror:18,parser:[0,15],part:[2,3,8,12,14,17],partial:15,particular:16,pass:[0,10,15,19],path:17,pattern:[5,14,17],pe1:[5,6],pe2:6,pearl:16,pend:[3,7,12,16,19],peopl:17,per:[7,14],perform:15,perhap:6,period:7,permit:[15,20],permut:15,persist:10,phase:2,pick:[5,6,20],pickl:7,pictur:10,piec:12,pip:0,place:[3,5,7,15],plai:0,plu:3,plug:[6,12,14],point:[4,7,10,12],pointless:2,pop:[3,5,6,7,10,12,13,14,20],popd:[3,7,8,10,13,15],popdd:[3,6,11,15],popop:[3,5,6,7,8,10,14,15],popopd:3,popopdd:3,posit:[3,5,7,12],possibilit:10,possibl:[10,14,15,17],post:7,poswrd:15,power:7,pragmat:5,preambl:8,precis:[0,1],pred:[3,15],predic:[2,3,6,12],prefix:[15,19],present:15,preserv:[4,14],pretti:[8,10,11,14,15,19,20],pretty_print:0,previou:7,primari:15,prime:8,primit:[2,3,15,17],primrec:[3,6,7,8,12],principl:15,print:[0,1,2,3,15,19,20],probabl:[6,7,10,15],problem:[7,15,17],proc_curr:10,proc_left:10,proc_right:10,proce:5,process:[7,14,15,19],produc:[5,10,12,14,15],product:[6,7,15],program:[0,2,3,6,7,8,10,12,15,16],programm:15,progress:15,project:17,prompt:7,proper:[2,3,12],properti:0,provabl:15,proven:15,provid:[0,3,4,7,15],pun:[0,7],punctuat:15,pure:0,puriti:7,purpos:7,push:[2,3,7,12,16,20],pushback:7,put:[1,2,6,7,15,17,20],pypi:0,python:[0,2,3,10,12,16,17,18,20],quadrat:[0,17],queri:[10,14],query_kei:14,queu:12,quit:[0,1,14],quot:[0,3,6,7,10,11,12,14,15,16,19],quotat:[2,3,12],quotient:3,r_kei:10,r_left:10,r_right:10,r_valu:10,rais:[10,15,18,20],rang:[7,15],range_revers:12,range_to_zero:7,ranger:12,ranger_revers:12,raphson:8,rather:[5,7,12,14],ratio:7,reach:[5,6,12],read:[0,1,5,6,10,15,16],readabl:13,reader:10,readi:15,real:10,realiz:[4,10],rearrang:[2,10,15],reason:[5,7,15],rebuild:[14,16],rec1:[2,3,12],rec2:[2,3,12],recent:15,recogn:18,record:[7,19],recur:[12,15],recurs:[0,2,3,6,7,8,15,17,20],recus:7,recycl:15,redefin:17,redistribut:[3,7],reduc:[2,15],redund:20,refactor:[7,9],refer:[0,2],regist:2,regular:[15,18],reimplement:17,relat:15,releas:9,remain:[2,7,9],remaind:[3,8],remind:15,remov:[3,10,15,20],render:17,repeat:5,repeatedli:5,repl:[0,1],replac:[0,2,3,6,11,12,14,15,16,17,20],repositori:0,repr:15,repres:[2,7,10,18,19],represent:20,reprod:6,repurpos:15,requir:[15,20],res:15,research:15,resembl:7,respect:5,rest:[3,5,6,7,10,12,16,17,20],rest_two:10,restat:15,restor:2,restrict:15,result:[1,2,3,5,10,11,12,14,15,16],resum:7,retain:15,retir:2,retri:7,reus:[10,15],revers:[3,5,6,12,15,16,20],revisit:15,rewrit:[3,7,15],rewritten:7,rich:15,rid:10,right:[6,7,11,14,15,17,19,20],rightest:10,rightmost:5,rkei:14,rob:15,robot:15,roll:[3,8,10,14],roll_dn:15,roll_down:[],roll_up:[],rolldown:[3,15],rollup:[3,15],root:[3,8,11],round:15,rrest:[3,15],rule:17,run:[0,1,3,5,7,8,10,11,12,14,16],runtimeerror:20,s1000:[],s1002:[],s23:[],sai:[6,10,11,14,15],same:[2,4,5,10,15,20],sandwich:[2,3,12],save:[2,5,7],scan:3,scanner:[7,18],scenario:16,scope:[6,10],search:[0,10],sec:15,second:[3,7,10,12,14,20],section:12,see:[0,6,7,8,9,11,12,13,15,16,19],seem:[0,5,7,14,15],seen:[15,16],select:3,self:15,semant:[2,3,7,9,10,15],semi:7,send:7,sens:[0,2,5,15,16],separ:[7,15],seq:15,sequenc:[0,1,2,3,5,7,10,12,13,16,17,18],sequence_to_stack:15,seri:[5,6,10,16],ses:15,set:[2,3,12,15,17],seven:[5,6],sever:[0,4,7,12],share:[3,7],shelf:2,shift:[5,6],shorter:17,shorthand:10,should:[2,3,5,10,12,15],shouldn:7,show:[4,16],shunt:[3,16],side:[10,15],signifi:[7,10],similar:[10,14,15],simon:7,simpl:[7,12,15,20],simplefunctionwrapp:[3,13,15],simpler:14,simplest:[15,17],simpli:4,simplifi:[5,10,16],sinc:[2,5,10,15],singl:[3,6,7,13,15,18],situ:10,situat:10,six:[5,6,7],sixti:[5,6],size:[7,17],skeptic:7,skip:15,slight:8,slightli:[10,12,15],smallest:3,smart:[10,15],softwar:[7,15],solei:2,solut:[5,6],solvabl:7,some:[2,3,6,7,10,12,14,15,17,20],somehow:[10,15],someth:[2,9,10,15],sometim:10,somewher:[10,17],sort:[3,10,15],sort_:3,sorta:15,sourc:[0,1,3,15,17,18,19,20],space:[5,19],span:5,spawn:15,special:[6,10,15,17],specif:[0,4],specifi:[10,15],speed:13,spell:14,sphinx:[17,20],spirit:[0,1,14],split:15,sqr:[7,8,11,16],sqrt:[3,8,15],squar:[3,8,15,18],stack:[0,1,3,5,6,8,10,11,12,13,14,16,17,18,19],stack_concat:15,stack_effect:15,stack_effect_com:15,stack_to_str:20,stacki:15,stackjoytyp:15,stackstarjoytyp:15,stage:14,stai:[0,1],stand:4,standard:[7,10],star:[14,15],stare:10,start:[5,6,7,8,10,12,14,15],state:7,statement:3,step:[3,5,7,10,13,15,16,17],still:[10,15],stop:10,storag:[5,10],store:[5,12],stori:12,str:[1,15,18,19,20],straightforward:[1,6,8,15,17],stream:5,stretch:10,string:[1,2,3,7,15,16,18,19,20],strip:15,structur:[7,14,15,16,17,20],stuff:[10,15],stuncon:3,stununcon:3,style:[0,4,15],sub:9,subclass:7,subject:16,subset:15,substitut:[10,15],subtract:5,subtyp:17,succ:[3,15],succe:15,success:8,suffic:15,suffici:10,suffix:15,suggest:[4,10],suitabl:[3,4,5],sum:[3,6,7,11,12,13,14,15],sum_:[3,15],summand:5,sumtre:14,suppli:[10,18],support:[7,15,19,20],suspect:2,swaack:[3,11,13,15,16],swap:[3,5,6,7,8,10,12,13,14,16],swarm:15,swon:[3,6,7,12,14,15,16],swoncat:[6,7,8,12,14],swuncon:12,symbol:[2,3,15,16,17,18],symboljoytyp:15,symmetr:[5,10],syntact:7,syntax:[7,20],sys:20,system:[7,10,15],tabl:15,tag:15,tail:[10,15,17,20],take:[3,5,7,8,10,12,15,20],talk:[7,10,15,20],target:16,tast:4,tbd:7,tear:12,technic:2,techniqu:[4,16],technolog:2,temporari:16,ten:5,term:[1,2,7,8,12,15,17,18,20],termin:[2,3,12],ternari:7,test:[2,3,12],text:[0,1,3,15],text_to_express:[7,15,18],textual:7,than:[0,3,5,6,7,8,12,14,15,20],thei:[2,5,6,7,10,12,15,16,18,20],them:[2,3,5,6,10,12,15,16,17],themselv:15,theori:[2,3,12],therefor:[6,15],thi:[0,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20],thing:[2,6,10,12,15,16,18,20],think:[2,5,7,10,12,14,15],third:[3,6,7,10],thirti:5,those:[2,3,10,12,15,17],though:5,thought:7,thousand:5,thread:2,three:[2,3,5,7,10,11,14,15,17],through:[1,5,7,14,15,16,20],thun:[2,3,4,9,12],thunder:7,time:[3,5,7,8,10,12,15,16],titl:15,to_set:10,todai:7,todo:[7,18],togeth:[6,7,15,17],token:18,toler:17,too:[12,15],tool:[7,15],tooo:15,top:[2,3,7,12,15,19,20],total:5,tower:15,trace:[0,7,11,12,16,17,20],traceback:15,traceprint:19,track:[11,15,16],tracker:0,transform:4,translat:[4,11,15],trash:15,travers:[0,17],treasur:0,treat:[0,2,3,12,15,17],treatment:6,tree:[0,7,17],treegrind:17,treestep:[0,17],tri:5,triangular_numb:12,trick:[5,15],tricki:15,trobe:0,trove:0,truli:15,trust:15,truthi:[3,7],tuck:[3,7,15],tupl:[3,7,15,20],ture:15,turn:[2,3,15],twice:[10,12],two:[2,3,5,7,8,10,11,12,14,15,16,17,20],type:[0,1,4,7,10,12,17,18,19,20],typeerror:15,typeless:15,typic:[2,3,11,12],unari:7,unarybuiltinwrapp:3,unbalanc:[10,18],unchang:10,uncompil:15,uncon:[3,6,7,10,12,14,16],under:[2,3,7,10],underli:15,underscor:15,understand:[0,10,15],undistinguish:10,undocu:7,unend:15,unfinish:15,unfortun:20,unif:15,uniqu:[3,10,15],unit:[7,12],univers:[0,7,15],unnecessari:17,unnecesssari:15,unpack:[2,3,10,20],unpair:5,unquot:[7,14],unstack:[3,15],unswon:3,untangl:12,until:6,unus:5,unusu:10,updat:[0,17],usag:7,use:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,20],used:[3,4,7,10,12,16,18,20],useful:[0,15],user:14,uses:[2,5,12],using:[3,6,10,11,12,14,16],usual:[0,2,12],util:[0,3,13,15],valid:15,valu:[0,2,3,5,7,8,11,12,13,14,15,17,20],value_n:10,valueerror:[15,20],variabl:[15,17],variant:10,variat:[12,17],varieti:[4,7],variou:0,vener:20,verbos:4,veri:[0,1,4,7,10,20],verifi:15,versa:[2,15],version:[0,1,2,6,9,14,16,17],via:7,vice:[2,15],view:[10,17],viewer:[1,7,9,19],vii:17,von:[0,2,3,4,12],wai:[0,2,3,4,5,7,12,13,15],wait:[],want:[2,5,6,8,10,12,15],warranti:[3,7],wash:7,wast:7,web:20,websit:[0,5],welcom:7,well:[0,4,7,8,10,15,18],were:[7,15,16],what:[2,3,4,7,10,12,14,15,19],whatev:[2,3,12,14,20],when:[5,6,7,10,12,15,16,18,20],where:[2,3,7,10,12,15,17,20],whether:12,which:[0,1,3,5,7,8,10,12,14,15,16,20],whole:[2,3,5,12,14,15],whose:6,why:[8,14],wiki:10,wikipedia:[0,10,16],wildli:7,wind:7,wire:12,within:[7,10,13,17],without:[2,7,10,11,15],won:[10,15,20],word:[0,3,5,7,12,16],work:[0,3,5,6,7,8,10,11,12,14,15,16,20],worth:5,would:[2,5,6,7,8,10,12,15,16,20],wrap:[3,7],wrapper:15,write:[4,8,10,12,14,15,16,17,20],written:[0,1,8,10,13,15,20],wrong:2,wrote:15,xrang:15,yang:15,year:[7,15],yet:[10,15,16],yield:[2,3,12,15,20],yin:17,you:[0,2,3,5,6,7,9,10,11,12,13,14,15,16,19,20],your:[2,3,7,12,15],yourself:[7,10],zero:[3,10,12,14,15,18,20],zip:[5,15],zip_:3,zipper:[0,17],zstr:16},titles:["Thun 0.2.0 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","Developing a Program in Joy","Using <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Recursive Combinators","Replacing Functions in the Dictionary","Treating Trees II: <code class=\"docutils literal notranslate\"><span class=\"pre\">treestep</span></code>","Type Inference","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026"],titleterms:{"abstract":15,"case":[8,10],"function":[2,3,7,8,10,12,13,14,15],"long":13,"new":10,"p\u00f6ial":15,"void":2,"while":2,Adding:10,One:[6,10],The:[5,7,10,12,14],There:7,Using:6,With:14,about:17,add:[2,10],adding:10,address:16,altern:14,ana:12,analysi:5,anamorph:[2,12],app1:2,app2:2,app3:2,appendix:[10,12,15],approxim:8,argument:15,auto:3,averag:2,base:[8,10],binari:[2,10,14],both:10,branch:[2,10],can:10,cata:12,catamorph:12,categor:4,chatter:2,child:10,choic:2,clear:2,cleav:2,cmp:10,code:[7,10],combin:[2,10,12,15],comment:15,compar:10,comparison:2,compil:[6,15],compile_:15,compos:15,comput:8,con:[2,15],concat:[2,15],conclus:12,consecut:8,continu:7,current:10,datastructur:[7,10,16],deal:15,defin:[10,14],definit:11,delabel:15,delet:10,deriv:[11,12,14],design:12,determin:16,develop:5,dialect:0,dictionari:13,dip:[2,16],dipd:2,dipdd:2,direco:6,disenstacken:2,distinguish:15,div:2,doc_from_stack_effect:15,document:0,doe:10,down_to_zero:2,drop:2,dup:[2,15],dupd:2,dupdip:2,effect:15,els:10,empti:10,enstacken:2,equal:10,essai:17,euler:[5,6],eval:7,even:6,exampl:[2,7,10,12,14],execut:19,express:[7,18],extract:14,factori:12,fibonacci:6,filter:5,find:[8,10,12],first:[2,5,15],five:6,flatten:2,flexibl:14,floordiv:2,formula:11,found:10,four:12,fun:12,further:5,gcd:2,gener:[3,5,6,8],genrec:2,get:[10,14],getitem:2,given:14,greater:10,group:2,have:[10,14],help:2,highest:10,host:0,how:[5,6],hylo:12,hylomorph:12,identifi:15,ift:2,iii:15,implement:15,indic:0,infer:15,inferenc:15,inform:0,infra:[2,16],integ:5,interest:6,interlud:10,intern:18,interpret:[1,7,15],item:16,iter:[5,10],joi:[0,1,3,5,7,12,15,16,17,18,19,20],junk:15,just:5,kei:10,languag:0,least_fract:2,left:10,less:10,let:5,librari:[3,7,15],like:10,list:[2,15,20],literari:7,littl:5,logic:[2,15],loop:[2,7],lower:10,lshift:2,make:[6,8],mani:5,map:2,math:2,method:8,min:2,miscellan:2,mod:2,modifi:15,modulu:2,more:10,most:10,mul:[2,15],multipl:[5,6,15],must:10,name:11,neg:2,newton:8,next:8,node:10,non:10,now:10,nullari:2,number:[12,15],one:7,onli:7,order:[10,14],osdn:0,our:10,over:2,pack:5,pam:2,para:12,paradigm:15,parameter:[10,14],pars:[2,18],parser:[7,18],part:15,pass:7,path:16,pattern:12,per:10,pop:[2,15],popd:2,popop:2,pow:2,power:6,pred:2,predic:[5,8,10,14],pretty_print:19,primit:12,primrec:2,print:7,problem:[5,6],process:10,product:2,program:[4,5,11,14,17],project:[0,5,6],pure:7,put:[10,11,14],python:[7,13,15],quadrat:11,quick:0,quot:[2,20],rang:[2,5,12],range_to_zero:2,read:7,recur:[8,10],recurs:[10,12,14],redefin:[10,14],refactor:[5,10],refer:3,regular:7,reimplement:14,relabel:15,rem:2,remaind:2,remov:2,render:5,repl:7,replac:[10,13],repres:15,reset:6,rest:[2,15],revers:2,right:[10,16],rightmost:10,roll:[2,15],rolldown:2,rollup:2,rshift:2,rule:15,run:[2,6],second:[2,15],select:2,sequenc:[6,15,20],set:[8,10],shorter:13,should:7,shunt:2,simplest:5,size:[2,13],someth:[],sourc:10,special:12,sqr:[2,15],sqrt:[2,11],stack:[2,7,15,20],start:0,step:[2,12,14],straightforward:11,structur:10,style:7,sub:[2,10],subtyp:15,succ:2,sum:[2,5],swaack:2,swap:[2,15],swon:2,swoncat:2,symbol:[7,12],tabl:0,tail:12,take:2,term:[5,6,14],ternari:2,text:18,than:10,them:11,thi:10,third:[2,15],three:6,thun:[0,7],time:[2,6],togeth:[10,11,14],token:7,toler:8,trace:[13,19],traceprint:7,travers:[10,14,16],treat:[10,14],tree:[10,14,16],treegrind:14,treestep:14,triangular:12,truediv:2,truthi:2,tuck:2,two:6,type:15,unari:2,unbound:15,uncon:[2,15],unifi:15,unit:2,unnecessari:5,unquot:2,unstack:2,updat:[9,15],use:15,util:[19,20],valu:[6,10],variabl:11,variat:6,version:[5,10,13,15],view:7,vii:15,within:8,word:2,write:11,xor:2,yin:15,zero:6,zip:2,zipper:16}})
\ No newline at end of file
+Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Recursion_Combinators","notebooks/Replacing","notebooks/Treestep","notebooks/Types","notebooks/Zipper","notebooks/index","parser","pretty","stack"],envversion:52,filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Recursion_Combinators.rst","notebooks/Replacing.rst","notebooks/Treestep.rst","notebooks/Types.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst"],objects:{"joy.joy":{joy:[1,1,1,""],repl:[1,1,1,""],run:[1,1,1,""]},"joy.library":{"void":[3,1,1,""],BinaryBuiltinWrapper:[3,1,1,""],DefinitionWrapper:[3,2,1,""],FunctionWrapper:[3,1,1,""],SimpleFunctionWrapper:[3,1,1,""],UnaryBuiltinWrapper:[3,1,1,""],add_aliases:[3,1,1,""],app1:[3,1,1,""],app2:[3,1,1,""],app3:[3,1,1,""],b:[3,1,1,""],branch:[3,1,1,""],choice:[3,1,1,""],clear:[3,1,1,""],cmp_:[3,1,1,""],concat_:[3,1,1,""],cond:[3,1,1,""],dip:[3,1,1,""],dipd:[3,1,1,""],dipdd:[3,1,1,""],divmod_:[3,1,1,""],drop:[3,1,1,""],dupdip:[3,1,1,""],floor:[3,1,1,""],genrec:[3,1,1,""],getitem:[3,1,1,""],help_:[3,1,1,""],i:[3,1,1,""],id_:[3,1,1,""],ifte:[3,1,1,""],infra:[3,1,1,""],initialize:[3,1,1,""],inscribe:[3,1,1,""],loop:[3,1,1,""],map_:[3,1,1,""],max_:[3,1,1,""],min_:[3,1,1,""],parse:[3,1,1,""],pm:[3,1,1,""],pred:[3,1,1,""],remove:[3,1,1,""],reverse:[3,1,1,""],select:[3,1,1,""],sharing:[3,1,1,""],shunt:[3,1,1,""],sort_:[3,1,1,""],sqrt:[3,1,1,""],step:[3,1,1,""],succ:[3,1,1,""],sum_:[3,1,1,""],swaack:[3,1,1,""],take:[3,1,1,""],times:[3,1,1,""],unique:[3,1,1,""],unstack:[3,1,1,""],warranty:[3,1,1,""],words:[3,1,1,""],x:[3,1,1,""],zip_:[3,1,1,""]},"joy.library.DefinitionWrapper":{add_def:[3,3,1,""],add_definitions:[3,3,1,""],parse_definition:[3,3,1,""]},"joy.parser":{ParseError:[18,4,1,""],Symbol:[18,2,1,""],text_to_expression:[18,1,1,""]},"joy.utils":{generated_library:[3,0,0,"-"],pretty_print:[19,0,0,"-"],stack:[20,0,0,"-"]},"joy.utils.generated_library":{ccons:[3,1,1,""],cons:[3,1,1,""],dup:[3,1,1,""],dupd:[3,1,1,""],dupdd:[3,1,1,""],first:[3,1,1,""],first_two:[3,1,1,""],fourth:[3,1,1,""],over:[3,1,1,""],pop:[3,1,1,""],popd:[3,1,1,""],popdd:[3,1,1,""],popop:[3,1,1,""],popopd:[3,1,1,""],popopdd:[3,1,1,""],rest:[3,1,1,""],rolldown:[3,1,1,""],rollup:[3,1,1,""],rrest:[3,1,1,""],second:[3,1,1,""],stack:[3,1,1,""],stuncons:[3,1,1,""],stununcons:[3,1,1,""],swap:[3,1,1,""],swons:[3,1,1,""],third:[3,1,1,""],tuck:[3,1,1,""],uncons:[3,1,1,""],unswons:[3,1,1,""]},"joy.utils.pretty_print":{TracePrinter:[19,2,1,""]},"joy.utils.pretty_print.TracePrinter":{go:[19,5,1,""],viewer:[19,5,1,""]},"joy.utils.stack":{concat:[20,1,1,""],expression_to_string:[20,1,1,""],iter_stack:[20,1,1,""],list_to_stack:[20,1,1,""],pick:[20,1,1,""],stack_to_string:[20,1,1,""]},joy:{joy:[1,0,0,"-"],library:[3,0,0,"-"],parser:[18,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","classmethod","Python class method"],"4":["py","exception","Python exception"],"5":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:classmethod","4":"py:exception","5":"py:method"},terms:{"0b11100111011011":5,"23rd":15,"4b4cb6ff86e5":[],"58a8e44e9cba":15,"5bkei":10,"5eb7ac5ad2c2":[],"7fde90b4e88f":[],"\u03b5":8,"abstract":[7,10,17],"boolean":[2,3,7,10],"break":[7,15],"byte":5,"case":[2,3,12,14,15,20],"class":[3,7,15,18,19,20],"default":[3,6,10,20],"export":[3,18],"final":[2,10,12],"float":[3,7,15,16,18],"function":[0,1,4,5,6,9,11,16,17,18,19,20],"g\u00e9rard":16,"import":[2,5,6,8,10,11,12,13,14,15,16],"int":[6,7,12,15,16,18,20],"long":[10,15,17],"new":[2,3,6,7,9,12,13,15],"p\u00f6ial":17,"p\u00f6ial06typingtool":15,"public":9,"return":[1,3,5,7,10,12,13,14,15,18,19,20],"static":[2,9],"super":15,"switch":[2,15],"throw":10,"true":[2,3,5,12,15],"try":[6,8,11,12,14,15],"void":[0,3],"while":[3,7,10,15,18,20],AND:15,Adding:[7,13,17],And:[5,6,8,10,12,15,16,20],But:[0,4,5,6,7,10,13,15],CPS:7,FNs:15,For:[2,3,10,12,13,15,17,20],Has:3,Its:3,Not:15,One:[2,7,15,17],TOS:[2,3],That:[5,10],The:[0,1,2,3,4,6,8,9,11,15,16,17,18,20],Then:[2,3,10,11,12,15],There:[11,12,14,15,20],These:[15,17,20],Use:[3,8,12],Using:[0,8,10,17],With:[8,12,15,17],_1000:15,__add__:15,__class__:15,__eq__:15,__ge__:15,__hash__:15,__init__:15,__main__:15,__name__:15,__radd__:15,__repr__:15,__str__:19,_ge:15,_names_for:15,_to_str:15,_tree_add_:10,_tree_add_e:10,_tree_add_p:10,_tree_add_r:10,_tree_add_t:10,_tree_delete_:10,_tree_delete_clear_stuff:10,_tree_delete_del:10,_tree_delete_r0:10,_tree_delete_r1:10,_tree_delete_rightmost:10,_tree_delete_w:10,_tree_get_:10,_tree_get_p:10,_tree_get_r:10,_tree_get_t:10,_tree_iter_order_curr:10,_tree_iter_order_left:10,_tree_iter_order_r:10,_tree_iter_order_right:10,_tree_t:10,_treestep_0:14,_treestep_1:14,_uniqu:15,_within_b:8,_within_p:8,_within_r:8,a10001:15,a10002:15,a10003:15,a10004:15,a1001:[],abbrevi:14,abil:15,abl:15,about:[0,7,10,15,16,20],abov:[0,5,8,10,12,15],abs:8,absolut:7,accept:[1,2,3,5,6,7,10,11,13,14,15,16],accordingli:10,accumul:5,action:[7,13,15,16],actual:[2,5,7,10,15],adapt:17,add:[3,5,6,7,13,15,19],add_alias:3,add_def:3,add_definit:[3,10,14],added:[4,10],adding:[9,15],addit:[0,2,3,5,7,12,13,14],address:17,adjust:10,after:[5,6,7,12],afterward:7,again:[2,3,5,7,10,12,15],aggreg:16,ahead:15,aka:[7,16],albrecht:0,algorithm:[7,15],alia:3,alias:[3,7],align:[7,19],all:[3,5,6,7,10,12,13,14,15,19],alloc:15,allow:[9,10],almost:10,along:[7,12,15],alphabet:3,alreadi:[8,13,15,16],also:[0,5,7,10,15,20],alter:15,altern:[4,15],although:[4,10],altogeth:6,alwai:[5,9,12],amaz:[],among:15,amort:10,analysi:[4,17],anamorph:[7,17],ani:[4,5,7,9,10,15,16,18],annual:7,anonym:10,anoth:[10,15,20],anyhow:[],anyjoytyp:15,anymor:15,anystarjoytyp:15,anyth:[2,3,7,15],apart:15,api:9,app1:3,app2:[3,7,11,12,13],app3:3,app:7,appear:[2,4,5,10],append:15,appendix:17,appli:[2,3,5,6,10,12,15],applic:6,approach:5,approxim:17,archiv:0,aren:16,arg:[2,3],argument:[2,3,7,8,11,12,17,19,20],arithmet:2,ariti:2,around:[5,15,20],arrang:14,arriv:[6,14],articl:[0,4,6,12],ask:[4,6,15],aspect:0,assert:15,assign:20,associ:10,assum:8,astar:15,asterisk:14,asterix:15,attack:7,attempt:[0,1],attribut:3,attributeerror:15,author:15,auto:[0,15],automat:[4,15],auxiliari:14,avail:[0,15],averag:[7,13],avoid:10,awai:10,awar:2,awkward:[10,12],azur:17,back:[10,15],backward:[9,10,11,14],bad:15,bag:7,banana:12,barb:12,base:[0,2,3,9,12,14,15],basic:[1,2,3,7,10,15],becaus:[2,3,7,10,14,15,16,20],becom:[10,14,20],becuas:15,been:[8,9,10,15,16],befor:[6,7,10],begin:[10,14],behavior:[9,14],behaviour:[0,1,15],being:0,below:[2,3,5,6,10,15,16],bespok:7,best:0,better:[5,10,12,15],between:[0,5],beyond:6,biannual:7,binari:[0,6,7,17],binary_search_tre:10,binarybuiltinwrapp:3,bind:7,bingo:16,bit:[5,6,10,15],block:5,bodi:[2,7,10],body_text:3,booktitl:15,bool:[12,15],borrow:[7,15],both:[2,5,7,11,12,13,15,20],bottom:6,bracket:[7,15,18],branch:[3,5,6,12,15],branch_fals:15,branch_tru:15,breakpoint:7,bring:[5,7,15],bruijn:15,brzozowski:15,btree:[10,14],buck:10,bug:[0,7],build:[6,7,11,12,16,20],built:[11,15],bundl:[2,3,12],burgeon:7,calculu:4,call:[2,7,9,10,12,15,19,20],caller:[10,15],can:[0,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,20],cannot:15,captur:7,card:7,care:[5,20],carefulli:16,carri:[6,10],cartesian:4,catamorph:17,categor:[0,17],categori:4,ccc:4,ccon:[3,10,15],cell:[12,15],certain:[7,20],certainli:10,chain:[3,15],chang:[2,9,10,15,16],charact:16,chat:7,chatter:[0,15],check:[6,8,15],checker:15,child:14,choic:[3,12],choos:9,chop:11,cinf:10,circuit:4,cite_not:10,classmethod:3,claus:[3,15],clean:15,clear:[3,5,7],clear_stuff:10,cleav:[7,11,13],close:[0,1,4,15],clunki:[5,15],cmp:[3,14,17],cmp_:3,code:[0,1,4,11,12,15,17],codireco:[6,8],collaps:12,collect:[4,6,7,15],combin:[0,3,5,6,7,8,11,14,16,17],combinatorjoytyp:15,combo:15,come:[7,10,15],command:[7,10,15],common:[2,5],compar:[3,4,15],comparison:[0,10],compel:4,compil:[2,4,7,10,13,17],complet:4,complex:[3,15,16],complic:15,composit:15,compostit:15,compound:10,comput:[2,4,5,7,11,15],con:[3,5,6,7,8,10,11,12,14,16,20],conal:4,concat:[3,6,7,14,20],concat_:3,concaten:0,concatin:[0,3,20],conclus:17,concurr:2,cond:[3,10],condit:[3,7],confer:15,conflict:[10,15],conjectur:15,consecut:17,consid:[5,6,10,12,14,15,16],consist:[2,6,7,14],constant:10,constitu:12,constraint:15,construct:15,consum:15,contain:[0,2,3,6,7,12],content:15,context:2,conting:10,continu:[0,12,15,16],control:7,conveni:[4,15],convers:15,convert:[12,13,14,15,18,20],cool:10,copi:[2,3,5,10,12,14,17],copyright:7,correct:[],correspond:4,could:[2,4,5,7,9,10,15,16],count:[3,15],counter:[5,15],coupl:14,cours:[5,10,15],cover:15,crack:10,crap:15,crash:10,creat:[0,2,3,5,8,10,15],creativ:15,crude:[10,15,18],crunchi:15,currect:[],current:[2,3,7,12,14,15,16,19],custom:9,cycl:[5,6],cython:7,dai:7,data:[2,3,12],datastructur:[0,2,12,15,17,18,20],datatyp:20,ddee30dbb1a6:[],ddididi:16,deal:[0,10],dealt:15,debugg:15,decid:10,declar:15,decor:3,decoupl:12,decrement:3,deduc:[5,15],deeper:0,deepli:4,def:[3,7,12,13,15,20],defaultdict:15,defi:3,defin:[2,3,4,5,6,7,8,9,11,12,13,15,16,17],definit:[2,3,5,6,7,9,10,12,14,15,17],definitionwrapp:[3,10,12,14],deleg:7,delet:17,deliber:15,demonstr:4,depend:[3,10,12],deposit:14,depth:[],dequot:12,der:10,deriv:[2,3,5,7,8,10,15,17],describ:[3,4,10,12,14,15,18],descript:[5,7],descriptor:15,design:[2,3,10,17],desir:[7,14],destruct:10,detail:[7,10,15],detect:[6,10,12,15],determin:17,develop:[0,6,7,15,17],diagram:5,dialect:1,dict:[1,3,15],dictionari:[0,1,3,7,15,17],did:15,differ:[0,4,5,8,10,11,12,20],differenti:4,difficult:15,dig:[10,16],digit:5,dinfrirst:7,dip:[3,5,6,7,8,10,11,12,13,14,15,17],dip_a:15,dip_t:15,dipd:[3,6,7,10,11,12,15,16],dipdd:[3,10,15],direco:17,direct:7,directli:[5,14,15,20],disappear:[2,15],discard:[3,6,8,10,12],disciplin:10,disenstacken:7,disk:7,displac:2,displai:15,distiguish:15,ditch:10,div:[3,7],dive:14,divis:10,divmod:3,divmod_:[3,15],doc:[2,3,7,15],docstr:15,document:[17,18,20],doe:[0,1,4,6,7,13,15,17,19],doesn:[5,9,10,14,15,20],doing:[4,5,7,15,16],domain:[4,15],don:[5,7,10,15],done:[2,5,7,9,15],dooooc:15,door:7,dot:19,doubl:[5,7,15],down:[2,8,12,16],down_to_zero:7,dozen:7,draft:[4,9],dream:7,drive:[6,8],driven:5,driver:6,drop:[3,10],dudipd:7,due:15,dup:[3,5,6,7,8,10,11,12,16,20],dupd:[3,15],dupdd:3,dupdip:[3,5,10,11,12,15],duplic:[3,10,12],durat:2,dure:[2,12],each:[2,3,4,5,7,12,13,14,15,19],easi:[0,10,14,15,16],easier:[3,10],easili:4,edit:17,effect:[2,3,7,16,17],effici:[6,13,16],either:[1,2,3,10,12,15],elabor:15,eleg:[7,10,15],element:2,elif:15,elimin:15,elliott:4,els:[2,3,12,15],else_:15,embed:[4,10,16],emit:15,empti:[3,7,14,15,20],encapsul:7,enclos:7,encod:6,encount:15,end:[5,10,12,14,15,20],endless:6,enforc:[2,7],engend:7,enorm:[],enough:[7,12,19],enstacken:[6,7,15],enter:7,entir:20,entri:[3,16,19],enumer:15,ephasi:15,epsilon:8,equal:[5,14,20],equat:[7,8],ergo:10,err:10,error:[7,15,18],essai:0,establish:15,etc:[3,14,15,16,18],euler:17,euro:15,eval:[0,15],evalu:[1,2,3,7,8,10,11,12,13,14,15],event:15,eventu:15,ever:15,everi:6,everyth:[3,10,11,15],evolv:9,examin:12,exampl:[0,3,5,15,17,18,20],exce:6,except:[7,10,15,18],execut:[0,1,2,3,7,12,13,14,15,16,20],exend:15,exercis:10,exist:[4,10,15],expand:10,expect:[2,3,14,15,20],experi:[7,14],explain:15,explan:7,explor:7,express:[0,1,2,3,4,10,12,13,15,16,19,20],expression_to_str:20,extend:15,extra:[5,6],extract:[10,11,17],extrem:7,extrememli:7,f1001:[],f_g:15,f_in:15,f_out:15,f_python:15,facet:0,facil:7,fact:[15,18],factor:[2,5,7,10,15],factori:17,fail:[2,3,10,18],fairli:15,fale:[],fall:15,fals:[2,3,5,12,15],falsei:15,far:[8,10,12,15],fascin:0,fear:[10,15],few:[5,7,8,11],fewer:[3,7],fg_in:15,fg_out:15,fib:6,fib_gen:6,fibonacci:17,figur:[2,3,10,12,15],filter:10,fin:5,find:[2,3,5,6,14,15,17],finder:8,fine:[0,5,10,15],first:[3,6,7,8,10,11,12,13,14,16,17],first_two:[3,10],fit:[5,7],five:[5,7,17],fix:[2,3,12,15],fixm:15,flag:15,flatten:[7,14,15],flexibl:17,floatjoytyp:15,floatstarjoytyp:15,floor:3,floordiv:5,flow:7,follow:[0,2,3,7,9,12,14,15,16],foo:[7,9,10,15],foo_ii:9,form:[2,3,4,5,6,12,14,15,20],forman:7,format:[15,17,19],formula:[0,5,17],forth:[7,15],forum:0,forward:15,found:7,foundat:[],four:[2,3,5,6,7,10,17],fourteen:5,fourth:[2,3,10,12],fractal:7,fraction0:7,fraction:[2,7],frame:12,framework:7,free:[4,7,10],freeli:2,from:[0,1,2,3,5,6,7,8,10,11,12,13,14,15,16,17,20],from_iter:15,front:[2,3,12,15],full:5,fulli:[],fun:17,func:15,functionjoytyp:15,functionwrapp:3,funtion:10,further:[8,15,17],g_in:15,g_out:15,garbag:7,gari:10,gcd:7,gener:[0,2,4,12,15,17,20],generated_librari:3,genrec:[3,7,10,12,14,15],geometr:5,get:[2,4,5,6,7,11,12,15,17],getitem:3,getrecursionlimit:20,getsourc:7,ghc:4,give:[4,5,10,12,14,15,20],given:[2,3,5,6,8,10,12,15,16,17],global:15,glue:7,going:[10,11,14,15,16],good:[5,10,15],grab:[3,15],grammar:18,grand:7,great:[0,7,15,17],greater:20,grok:[],group:0,gsra:8,guard:10,had:[5,16],haiku:7,half:[5,15,16],hand:[7,13,15,17],handi:[8,15],handl:[10,15,20],happen:[7,15],hard:[15,16],hardwar:4,has:[0,2,6,7,8,9,10,12,15,16,20],hasattr:15,hash:15,haskel:4,have:[2,3,5,6,7,8,9,12,13,15,16,17,20],haven:[],head:20,help:[7,10,12,15],help_:3,helper:3,herd:7,here:[5,6,10,14,15,16],hide:10,hierarchi:15,higher:[7,10,15],highli:7,histori:[15,19],hmm:10,hoist:3,hold:[5,15],hood:10,hope:[0,5,7,15,17],hopefulli:12,host:17,how:[0,4,8,10,12,15,16,17],howev:[12,13,15],html:[2,3,6,11,12,17],http:10,huet:16,huge:10,hugh:[8,14],human:[7,15],hybrid:15,hylomorph:17,hypothet:2,id_:3,idea:[4,5,7,15],ident:[3,12,15],if_not_empti:10,ift:[3,10,12,14,15],ignor:[3,10,15],iii:17,illustr:12,imagin:16,imap:15,imit:14,immedi:12,immut:[7,10],imper:12,implement:[0,1,2,3,4,7,9,10,12,13,17],impli:[],implicit:7,improv:15,includ:[4,10,14,15],inclus:5,incom:20,incompat:9,incorpor:11,increas:5,increment:[3,4,5,9],index:[0,7,15,20],indexerror:[15,20],indic:[14,15],ineffici:15,infer:[0,17],inform:[3,15],infra:[3,6,7,10,11,13,14,15,17],infrastructur:3,initi:[2,3,7,8,10],inlin:10,inner:15,inproceed:15,input:[1,8,15],inscrib:3,insert:15,insight:12,inspect:7,instal:0,instanc:15,instanti:[4,19],instead:[5,6,10,12,15,16,20],integ:[2,3,7,12,14,15],integr:3,intend:[0,7],interact:[7,17],interest:[0,5,10,15,17],interlud:17,intermedi:12,intern:[0,15,19,20],interpret:[0,4,9,13,17,18,19],interrupt:7,interv:[4,5],intjoytyp:15,introduc:9,introduct:0,intstarjoytyp:15,intuit:15,invari:3,invent:15,involv:15,ipf:7,ipython:15,isinst:15,isn:[10,16],issubclass:15,item:[2,3,7,10,12,14,15,17,20],iter:[1,3,7,12,14,15,17,20],iter_stack:[13,15,20],iteritem:15,itertool:15,its:[0,2,3,4,5,7,10,12,14,15,20],itself:[0,2,7,10,15],j05cmp:[2,3,12],jaanu:15,job:17,john:[8,14],joi:[2,4,9,10,11,13],join:15,joypi:[7,16],june:15,junk:17,jupyt:17,just:[0,2,3,6,7,9,10,12,14,15,16],kav:15,keep:[10,11,15,16],kei:[14,17],kevin:0,key_n:10,keyerror:[10,15],kind:[2,4,7,10,12,14,15],kinda:15,kjs:15,kleen:[14,15],kleenestar:15,kleffner:15,know:[5,10,15],knowledg:15,known:4,l2s:15,l_kei:10,l_left:10,l_right:10,l_valu:10,label:15,lambda:[4,15],languag:[4,7,9,10,13,15],larg:15,larger:20,largest:3,last:[5,10,12,15],lastli:6,later:[7,14,15],law:2,lazi:15,lazili:8,lcm:5,lead:[7,15],leaf:10,lean:7,learn:[0,15],least:[2,5,12,15,20],least_fract:7,leav:5,left:[7,11,12,14,15,16,19,20],leftov:12,len:15,length:[3,5,20],lens:12,less:[5,6,7,12,15,20],let:[6,8,10,11,12,14,15,16],letter:15,level:[4,10],librari:[0,13],like:[2,3,5,7,14,15,17,18],limit:15,line:[3,7,10,11,19],linear:20,link:0,linux:0,list:[0,3,5,7,8,10,12,14,15,16,19],list_to_stack:[15,20],lit:15,liter:[1,10,14,15,16,18],literatur:15,littl:[6,10,15,17],live:17,lkei:14,load:[5,7],local:15,locat:2,locu:19,lof:[],log_2:10,logic:[0,5,17],longer:[10,15],look:[6,7,8,10,11,15],lookup:7,loop:[0,1,3,5,15],lose:15,lot:[7,10,15,16],love:5,low:4,lower:5,lowercas:15,lowest:10,machin:0,machineri:[10,15],macro:7,made:[0,7,15,16],magic:15,mai:[2,12],mail:0,main:[0,3,7,11,15,16],mainloop:9,maintain:16,major:9,make:[2,3,4,5,7,10,12,13,14,15,16,17],make_gener:8,manfr:[0,2,3,4,12],mani:[0,7,15],manipul:15,manner:11,map:[1,3,5,7,9,12,14,15],map_:3,marker:7,mask:[5,6],match:[0,1],materi:[0,15],math:[0,7,8,10,11,15],mathemat:7,matter:[5,8,10,14],max_:3,maximum:3,mayb:[10,15],mean:[4,5,7,8,10,12,14,15,20],meant:[7,10,12,14],member:[2,3,12],mental:7,mention:2,mercuri:0,mess:15,messag:15,meta:[7,10,13],meta_compos:15,metal:[],method:[0,3,7,15,17,19],midpoint:5,might:[4,6,10,15],mike:10,million:6,min_:3,mind:15,minimum:3,minor:10,minu:3,mirror:0,miscellan:0,mix:[7,15],mod:3,mode:15,model:[4,7,15],modern:0,modif:6,modifi:[7,10,16],modul:[0,1,3,7,15,18],modulu:7,moment:15,month:7,more:[0,3,4,5,6,7,8,12,13,14,15,18,20],most:15,mostli:0,motiv:[],move:10,movement:2,much:[5,6,10,12,15],muck:10,mul:[7,11,16,19],multi:3,multipl:17,must:[2,3,5,9,12,14,15],myself:15,n10001:15,n10002:15,n10003:15,n1001:15,n1002:15,n1003:15,name:[1,3,7,9,10,12,15,16,17,18,20],narr:15,natur:[5,6,10],navig:16,nearli:15,neat:10,neato:15,necessarili:15,need:[2,3,5,6,8,9,10,12,15],neg:[3,11],neither:15,nest:[3,7,10,16],network:7,never:[9,12],new_def:15,new_f:15,new_fo:15,new_kei:10,new_valu:10,newton:[0,17],next:[5,14,15],nice:[0,12,20],niether:2,node:[14,17],node_kei:10,node_valu:10,non:[14,15],none:[1,3,15],nope:14,normal:15,notat:[7,10],note:[2,5,8,10,12,15,20],notebook:[5,6,7,15,16,17],notebook_preambl:[2,5,6,8,10,11,12,13,14,15,16],noth:[2,10],notic:5,now:[5,6,7,12,13,14,15,17],nth:[3,20],nullari:[7,10],number:[1,2,3,5,6,8,20],numberjoytyp:15,numberstarjoytyp:15,numer:15,object:[15,18],observ:5,obviou:6,obvious:15,occur:10,odd:[5,6],off:[2,3,5,6,11,15,16],okai:[],old:[2,13],old_k:10,old_kei:10,old_valu:10,omit:[12,15],onc:[3,9,10],one:[2,3,5,6,10,12,14,15,19,20],ones:[6,15],onli:[2,3,5,10,12,15,16,20],onto:[1,2,3,7,12,20],open:[7,15],oper:[3,7,10,12,20],oppos:15,optim:10,option:[1,7,10,20],order:[0,2,3,7,12,15,17,20],org:[0,10],origin:[0,1,2,3,10,16],other:[0,2,3,4,7,10,12,14,15,20],otherwis:[3,5,6,10,14,15],our:[5,6,7,8,12,14,15],out:[2,3,4,5,6,7,8,10,11,12,15,16],outcom:14,output:[8,12,15],outsid:4,over:[3,4,5,6,7,8,10,11,14,15,17],overhaul:15,overview:15,own:[10,15],pace:15,pack:20,packag:[0,7],page:[0,10,15,20],pair:[2,3,5,6,10,15],palidrom:5,palindrom:5,pam:7,paper:[4,7,12,16],paradigm:17,parallel:2,paramet:[1,2,3,12,13,18,19,20],parameter:17,paramorph:12,parenthes:[10,20],pariti:6,pars:[0,3,7],parse_definit:3,parseerror:18,parser:[0,15],part:[2,3,8,12,14,17],partial:15,particular:16,pass:[0,10,15,19],path:17,pattern:[5,14,17],pe1:[5,6],pe2:6,pearl:16,pend:[3,7,12,16,19],peopl:[15,17],per:[7,14],perform:15,perhap:6,period:7,permit:[15,20],permut:15,persist:10,phase:2,pick:[5,6,20],pickl:7,pictur:10,piec:12,pip:0,place:[3,5,7,15],plai:0,plu:3,plug:[6,12,14],point:[4,7,10,12],pointless:2,pop:[3,5,6,7,10,12,13,14,20],popd:[3,7,8,10,13,15],popdd:[3,6,11,15],popop:[3,5,6,7,8,10,14,15],popopd:3,popopdd:3,posit:[3,5,7,12],possibilit:10,possibl:[10,14,15,17],post:7,poswrd:15,power:7,pragmat:5,preambl:8,precis:[0,1],pred:[3,15],predic:[2,3,6,12],prefix:[15,19],present:15,preserv:[4,14],pretti:[8,10,11,14,15,19,20],pretty_print:0,previou:7,primari:[],prime:8,primit:[2,3,15,17],primrec:[3,6,7,8,12],principl:[],print:[0,1,2,3,15,19,20],probabl:[6,7,10,15],problem:[7,15,17],proc_curr:10,proc_left:10,proc_right:10,proce:5,process:[7,14,15,19],produc:[5,10,12,14,15],product:[6,7,15],program:[0,2,3,6,7,8,10,12,15,16],programm:15,progress:15,project:17,prolog:15,prompt:7,proper:[2,3,12],properti:0,provabl:[],proven:[],provid:[0,3,4,7],pun:[0,7],punctuat:15,pure:0,puriti:7,purpos:7,push:[2,3,7,12,16,20],pushback:7,put:[1,2,6,7,15,17,20],pypi:0,python:[0,2,3,10,12,16,17,18,20],quadrat:[0,17],queri:[10,14],query_kei:14,queu:12,quit:[0,1,14],quot:[0,3,6,7,10,11,12,14,15,16,19],quotat:[2,3,12],quotient:3,r_kei:10,r_left:10,r_right:10,r_valu:10,rais:[10,15,18,20],rang:[7,15],range_revers:12,range_to_zero:7,ranger:12,ranger_revers:12,raphson:8,rather:[5,7,12,14],ratio:7,reach:[5,6,12],read:[0,1,5,6,10,15,16],readabl:13,reader:10,readi:15,real:10,realiz:[4,10,15],rearrang:[2,10,15],reason:[5,7,15],rebuild:[14,16],rec1:[2,3,12],rec2:[2,3,12],recent:15,recogn:18,record:[7,19],recur:[12,15],recurs:[0,2,3,6,7,8,15,17,20],recus:7,recycl:[],redefin:17,redistribut:[3,7],reduc:[2,15],redund:20,refactor:[7,9],refer:[0,2],regist:2,regular:[15,18],reimplement:17,relat:15,releas:9,remain:[2,7,9,15],remaind:[3,8],remind:15,remov:[3,10,15,20],render:17,repeat:5,repeatedli:5,repl:[0,1],replac:[0,2,3,6,11,12,14,15,16,17,20],repositori:0,repr:15,repres:[2,7,10,18,19],represent:20,reprod:6,repurpos:15,requir:[15,20],res:15,research:15,resembl:7,respect:5,rest:[3,5,6,7,10,12,16,17,20],rest_two:10,restat:[],restor:2,restrict:15,result:[1,2,3,5,10,11,12,14,15,16],resum:7,retain:15,retir:2,retri:7,reus:[10,15],revers:[3,5,6,12,15,16,20],revisit:15,rewrit:[3,7,15],rewritten:[7,15],rich:15,rid:10,right:[6,7,11,14,15,17,19,20],rightest:10,rightmost:5,rkei:14,rob:15,robot:[],roll:[3,8,10,14],roll_dn:15,roll_down:[],roll_up:[],rolldown:[3,15],rollup:[3,15],root:[3,8,11],round:15,rrest:[3,15],rule:17,run:[0,1,3,5,7,8,10,11,12,14,16],runtimeerror:20,s1000:[],s1002:[],s23:[],sai:[6,10,11,14,15],same:[2,4,5,10,15,20],sandwich:[2,3,12],save:[2,5,7],scan:3,scanner:[7,18],scenario:16,scope:[6,10],search:[0,10],sec:15,second:[3,7,10,12,14,20],section:12,see:[0,6,7,8,9,11,12,13,15,16,19],seem:[0,5,7,14,15],seen:[15,16],select:3,self:15,semant:[2,3,7,9,10,15],semi:7,send:7,sens:[0,2,5,15,16],separ:[7,15],seq:15,sequenc:[0,1,2,3,5,7,10,12,13,16,17,18],sequence_to_stack:15,seri:[5,6,10,16],ses:15,set:[2,3,12,15,17],seven:[5,6],sever:[0,4,7,12],share:[3,7],shelf:2,shift:[5,6,15],shorter:17,shorthand:10,should:[2,3,5,10,12,15],shouldn:7,show:[4,16],shunt:[3,16],side:[10,15],signifi:[7,10],similar:[10,14,15],simon:7,simpl:[7,12,15,20],simplefunctionwrapp:[3,13,15],simpler:14,simplest:[15,17],simpli:4,simplifi:[5,10,16],sinc:[2,5,10,15],singl:[3,6,7,13,15,18],situ:10,situat:10,six:[5,6,7],sixti:[5,6],size:[7,17],skeptic:7,skip:15,slight:8,slightli:[10,12,15],smallest:3,smart:10,softwar:7,solei:2,solut:[5,6],solvabl:7,some:[2,3,6,7,10,12,14,15,17,20],somehow:[10,15],someth:[2,9,10,15],sometim:10,somewher:[10,17],sort:[3,10,15],sort_:3,sorta:15,sourc:[0,1,3,15,17,18,19,20],space:[5,19],span:5,spawn:15,special:[6,10,15,17],specif:[0,4],specifi:[10,15],speed:13,spell:14,sphinx:[17,20],spirit:[0,1,14],split:15,sqr:[7,8,11,16],sqrt:[3,8,15],squar:[3,8,15,18],squishi:15,stack:[0,1,3,5,6,8,10,11,12,13,14,16,17,18,19],stack_concat:[],stack_effect:15,stack_effect_com:15,stack_to_str:20,stacki:15,stackjoytyp:15,stackstarjoytyp:15,stage:14,stai:[0,1],stand:4,standard:[7,10],star:[14,15],stare:10,start:[5,6,7,8,10,12,14,15],state:7,statement:3,step:[3,5,7,10,13,15,16,17],still:[10,15],stop:10,storag:[5,10],store:[5,12],stori:12,str:[1,15,18,19,20],straightforward:[1,6,8,15,17],stream:5,stretch:10,string:[1,2,3,7,15,16,18,19,20],strip:15,structur:[7,14,15,16,17,20],stuff:[10,15],stuncon:3,stununcon:3,style:[0,4,15],sub:9,subclass:7,subject:16,subset:15,substitut:[10,15],subtract:5,subtyp:17,succ:[3,15],succe:15,success:8,suck:15,suffic:15,suffici:10,suffix:15,suggest:[4,10],suitabl:[3,4,5],sum:[3,6,7,11,12,13,14,15],sum_:[3,15],summand:5,sumtre:14,suppli:[10,18],support:[7,15,19,20],suspect:2,swaack:[3,11,13,15,16],swap:[3,5,6,7,8,10,12,13,14,16],swarm:[],swon:[3,6,7,12,14,15,16],swoncat:[6,7,8,12,14],swuncon:12,symbol:[2,3,15,16,17,18],symboljoytyp:15,symmetr:[5,10],syntact:7,syntax:[7,20],sys:20,system:[7,10],tabl:15,tag:15,tail:[10,15,17,20],take:[3,5,7,8,10,12,15,20],talk:[7,10,15,20],target:16,tast:4,tbd:7,tear:12,technic:2,techniqu:[4,16],technolog:2,temporari:16,ten:5,term:[1,2,7,8,12,15,17,18,20],termin:[2,3,12],ternari:7,test:[2,3,12],text:[0,1,3,15],text_to_express:[7,15,18],textual:7,than:[0,3,5,6,7,8,12,14,15,20],thei:[2,5,6,7,10,12,15,16,18,20],them:[2,3,5,6,10,12,15,16,17],themselv:15,theori:[2,3,12],therefor:6,thi:[0,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20],thing:[2,6,10,12,15,16,18,20],think:[2,5,7,10,12,14,15],third:[3,6,7,10],thirti:5,those:[2,3,10,12,15,17],though:5,thought:7,thousand:5,thread:2,three:[2,3,5,7,10,11,14,15,17],through:[1,5,7,14,15,16,20],thun:[2,3,4,9,12],thunder:7,time:[3,5,7,8,10,12,15,16],titl:15,to_set:10,todai:7,todo:[7,18],togeth:[6,7,15,17],token:18,toler:17,too:[12,15],tool:[7,15],tooo:15,top:[2,3,7,12,15,19,20],total:5,tower:15,trace:[0,7,11,12,16,17,20],traceback:15,traceprint:19,track:[11,15,16],tracker:0,transform:4,translat:[4,11,15],trash:[],travers:[0,17],treasur:0,treat:[0,2,3,12,15,17],treatment:6,tree:[0,7,17],treegrind:17,treestep:[0,17],tri:5,triangular_numb:12,trick:[5,15],tricki:15,trobe:0,trove:0,truli:[],trust:[],truthi:[3,7,15],tuck:[3,7,15],tupl:[3,7,15,20],ture:[],turn:[2,3,15],twice:[10,12],two:[2,3,5,7,8,10,11,12,14,15,16,17,20],type:[0,1,4,7,10,12,17,18,19,20],typeerror:15,typeless:15,typic:[2,3,11,12],unari:7,unarybuiltinwrapp:3,unbalanc:[10,18],unchang:10,uncompil:15,uncon:[3,6,7,10,12,14,16],under:[2,3,7,10],underli:15,underscor:15,understand:[0,10],undistinguish:10,undocu:7,unend:[],unfinish:15,unfortun:20,unicod:15,unif:15,uniqu:[3,10,15],unit:[7,12],univers:[0,7,15],unnecessari:17,unnecesssari:15,unpack:[2,3,10,20],unpair:5,unquot:[7,14],unstack:[3,15],unswon:3,untangl:12,until:6,unus:5,unusu:10,updat:[0,17],usag:7,use:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,20],used:[3,4,7,10,12,16,18,20],useful:[0,15],user:14,uses:[2,5,12],using:[3,6,10,11,12,14,16],usual:[0,2,12],util:[0,3,13,15],valid:15,valu:[0,2,3,5,7,8,11,12,13,14,15,17,20],value_n:10,valueerror:[15,20],variabl:[15,17],variant:10,variat:[12,17],varieti:[4,7],variou:0,vener:20,verbos:4,veri:[0,1,4,7,10,20],verifi:15,versa:[2,15],version:[0,1,2,6,9,14,16,17],via:7,vice:[2,15],view:[10,17],viewer:[1,7,9,19],vii:17,visibl:15,von:[0,2,3,4,12],wai:[0,2,3,4,5,7,12,13,15],wait:[],want:[2,5,6,8,10,12,15],warranti:[3,7],wash:7,wast:7,web:20,websit:[0,5],welcom:7,well:[0,4,7,8,10,15,18],went:15,were:[7,15,16],what:[2,3,4,7,10,12,14,15,19],whatev:[2,3,12,14,20],when:[5,6,7,10,12,15,16,18,20],where:[2,3,7,10,12,15,17,20],whether:12,which:[0,1,3,5,7,8,10,12,14,15,16,20],whole:[2,3,5,12,14,15],whose:6,why:[8,14],wiki:10,wikipedia:[0,10,16],wildli:7,wind:7,wire:12,within:[7,10,13,17],without:[2,7,10,11,15],won:[10,15,20],word:[0,3,5,7,12,16],work:[0,3,5,6,7,8,10,11,12,14,15,16,20],worth:5,would:[2,5,6,7,8,10,12,15,16,20],wrap:[3,7],wrapper:15,write:[4,8,10,12,14,15,16,17,20],written:[0,1,8,10,13,15,20],wrong:2,wrote:15,xrang:15,yang:15,year:[7,15],yet:[10,15,16],yield:[2,3,12,15,20],yin:17,you:[0,2,3,5,6,7,9,10,11,12,13,14,15,16,19,20],your:[2,3,7,12,15],yourself:[7,10],zero:[3,10,12,14,15,18,20],zip:[5,15],zip_:3,zipper:[0,17],zstr:16},titles:["Thun 0.2.0 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","Developing a Program in Joy","Using <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Recursive Combinators","Replacing Functions in the Dictionary","Treating Trees II: <code class=\"docutils literal notranslate\"><span class=\"pre\">treestep</span></code>","Type Inference","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026"],titleterms:{"abstract":15,"case":[8,10],"function":[2,3,7,8,10,12,13,14,15],"long":13,"new":10,"p\u00f6ial":15,"void":2,"while":2,Adding:10,One:[6,10],The:[5,7,10,12,14],There:7,Using:6,With:14,about:17,add:[2,10],adding:10,address:16,altern:14,ana:12,analysi:5,anamorph:[2,12],app1:2,app2:2,app3:2,appendix:[10,12,15],approxim:8,argument:15,auto:3,averag:2,base:[8,10],binari:[2,10,14],both:10,branch:[2,10],can:10,cata:12,catamorph:12,categor:4,chatter:2,child:10,choic:2,clear:2,cleav:2,cmp:10,code:[7,10],combin:[2,10,12,15],comment:15,compar:10,comparison:2,compil:[6,15],compile_:15,compos:15,comput:8,con:[2,15],concat:[2,15],conclus:[12,15],consecut:8,continu:7,current:10,datastructur:[7,10,16],deal:15,defin:[10,14],definit:11,delabel:15,delet:10,deriv:[11,12,14],design:12,determin:16,develop:5,dialect:0,dictionari:13,dip:[2,16],dipd:2,dipdd:2,direco:6,disenstacken:2,distinguish:15,div:2,doc_from_stack_effect:15,document:0,doe:10,down_to_zero:2,drop:2,dup:[2,15],dupd:2,dupdip:2,effect:15,els:10,empti:10,enstacken:2,equal:10,essai:17,euler:[5,6],eval:7,even:6,exampl:[2,7,10,12,14],execut:19,express:[7,18],extract:14,factori:12,fibonacci:6,filter:5,find:[8,10,12],first:[2,5,15],five:6,flatten:2,flexibl:14,floordiv:2,formula:11,found:10,four:12,fun:12,further:5,gcd:2,gener:[3,5,6,8],genrec:2,get:[10,14],getitem:2,given:14,greater:10,group:2,have:[10,14],help:2,highest:10,host:0,how:[5,6],hylo:12,hylomorph:12,identifi:15,ift:2,iii:15,implement:15,indic:0,infer:15,inferenc:15,inform:0,infra:[2,16],integ:5,interest:6,interlud:10,intern:18,interpret:[1,7,15],item:16,iter:[5,10],joi:[0,1,3,5,7,12,15,16,17,18,19,20],junk:15,just:5,kei:10,languag:0,least_fract:2,left:10,less:10,let:5,librari:[3,7,15],like:10,list:[2,20],literari:7,littl:5,logic:[2,15],loop:[2,7],lower:10,lshift:2,make:[6,8],mani:5,map:2,math:2,method:8,min:2,miscellan:2,mod:2,modifi:15,modulu:2,more:10,most:10,mul:[2,15],multipl:[5,6,15],must:10,name:11,neg:2,newton:8,next:8,node:10,non:10,now:10,nullari:2,number:[12,15],one:7,onli:7,order:[10,14],osdn:0,our:10,over:2,pack:5,pam:2,para:12,paradigm:15,parameter:[10,14],pars:[2,18],parser:[7,18],part:15,pass:7,path:16,pattern:12,per:10,pop:[2,15],popd:2,popop:2,pow:2,power:6,pred:2,predic:[5,8,10,14],pretty_print:19,primit:12,primrec:2,print:7,problem:[5,6],process:10,product:2,program:[4,5,11,14,17],project:[0,5,6],pure:7,put:[10,11,14],python:[7,13,15],quadrat:11,quick:0,quot:[2,20],rang:[2,5,12],range_to_zero:2,read:7,recur:[8,10],recurs:[10,12,14],redefin:[10,14],refactor:[5,10],refer:3,regular:7,reimplement:14,relabel:15,rem:2,remaind:2,remov:2,render:5,repl:7,replac:[10,13],repres:15,reset:6,rest:[2,15],revers:2,right:[10,16],rightmost:10,roll:[2,15],rolldown:2,rollup:2,rshift:2,rule:15,run:[2,6],second:[2,15],select:2,sequenc:[6,15,20],set:[8,10],shorter:13,should:7,shunt:2,simplest:5,size:[2,13],someth:[],sourc:10,special:12,sqr:[2,15],sqrt:[2,11],stack:[2,7,15,20],start:0,step:[2,12,14],straightforward:11,structur:10,style:7,sub:[2,10],subtyp:15,succ:2,sum:[2,5],swaack:2,swap:[2,15],swon:2,swoncat:2,symbol:[7,12],tabl:0,tail:12,take:2,term:[5,6,14],ternari:2,text:18,than:10,them:11,thi:10,third:[2,15],three:6,thun:[0,7],time:[2,6],togeth:[10,11,14],token:7,toler:8,trace:[13,19],traceprint:7,travers:[10,14,16],treat:[10,14],tree:[10,14,16],treegrind:14,treestep:14,triangular:12,truediv:2,truthi:2,tuck:2,two:6,type:15,unari:2,unbound:15,uncon:[2,15],unifi:15,unit:2,unnecessari:5,unquot:2,unstack:2,updat:[9,15],use:15,util:[19,20],valu:[6,10],variabl:11,variat:6,version:[5,10,13,15],view:7,vii:15,within:8,word:2,write:11,xor:2,yin:15,zero:6,zip:2,zipper:16}})
\ No newline at end of file
index 216ce90..a8084de 100644 (file)
@@ -3,42 +3,19 @@ Type Inference
 ==============
 
 This notebook presents a simple type inferencer for Joy code. It can
-infer the stack effect of most Joy expressions. It built largely by
-means of existing ideas and research (some of it may be original but I'm
-not able to say, as I don't fully understand the all of the source
-material in the depth required to make that call.) A great overview of
-the existing knowledge is a talk `"Type Inference in Stack-Based
-Programming
+infer the stack effect of most Joy expressions. It's built largely by
+means of existing ideas and research. (A great overview of the existing
+knowledge is a talk `"Type Inference in Stack-Based Programming
 Languages" <http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/>`__
 given by Rob Kleffner on or about 2017-03-10 as part of a course on the
-history of programming languages.
+history of programming languages.)
 
 The notebook starts with a simple inferencer based on the work of Jaanus
 Pöial which we then progressively elaborate to cover more Joy semantics.
 Along the way we write a simple "compiler" that emits Python code for
-what I like to call Yin functions.
-
-Yin functions are those that only rearrange values in stacks, as opposed
-to Yang functions that actually work on the values themselves. It's
-interesting to note that a Joy with *only* stacks (no other kinds of
-values) can be made and is Turing-complete, therefore all Yang functions
-are actually Yin functions, and all computation can be performed by
-manipulations of structures of containers, which is a restatement of the
-Laws of Form. (Also, this implies that every program can be put into a
-form such that it can be computed in a single step, although that step
-may be enormous or unending.)
-
-Although I haven't completed it yet, a Joy based on Laws of Form
-provides the foundation for a provably correct computing system "down to
-the metal". This is my original and still primary motivation for
-developing Joy. (I want a proven-correct Operating System for a swarm of
-trash-collecting recycler robots. To trust it I have to implementment it
-myself from first principles, and I'm not smart enough to truly grok the
-existing literature and software, so I had to go look for and find LoF
-and Joy. Now that I have the mental tools to build my robot OS I can get
-down to it.
-
-Anyhow, here's type inference...
+what I like to call Yin functions. (Yin functions are those that only
+rearrange values in stacks, as opposed to Yang functions that actually
+work on the values themselves.)
 
 Part I: Pöial's Rules
 ---------------------
@@ -235,8 +212,8 @@ function only rearranges the stack and doesn't do any actual processing
 on the stack items themselves all the information needed to implement it
 is in the stack effect comment.
 
-Functions on Lists
-~~~~~~~~~~~~~~~~~~
+Functions on Stacks
+~~~~~~~~~~~~~~~~~~~
 
 These are slightly tricky.
 
@@ -495,18 +472,12 @@ integers or tuples of type descriptors:
         if s is None:
             s = {}
     
-        if u == v:
-            return s
-    
         if isinstance(u, int):
             s[u] = v
-            return s
-    
-        if isinstance(v, int):
+        elif isinstance(v, int):
             s[v] = u
-            return s
     
-        return False
+        return s
 
 ``update()``
 ~~~~~~~~~~~~
@@ -738,12 +709,6 @@ work:
     except Exception, e:
         print e
 
-
-.. parsed-literal::
-
-    Cannot unify (1, 2) and (1001, 1002).
-
-
 ``unify()`` version 2
 ^^^^^^^^^^^^^^^^^^^^^
 
@@ -760,27 +725,24 @@ deal with this recursively:
             u = update(s, u)
             v = update(s, v)
     
-        if u == v:
-            return s
-    
         if isinstance(u, int):
             s[u] = v
-            return s
     
-        if isinstance(v, int):
+        elif isinstance(v, int):
             s[v] = u
-            return s
     
-        if isinstance(u, tuple) and isinstance(v, tuple):
-            if len(u) != len(v) != 2:
-                raise ValueError(repr((u, v)))
-            for uu, vv in zip(u, v):
-                s = unify(uu, vv, s)
-                if s == False: # (instead of a substitution dict.)
-                    break
-            return s
-     
-        return False
+        elif isinstance(u, tuple) and isinstance(v, tuple):
+    
+            if len(u) != 2 or len(v) != 2:
+                # Not a type error, caller passed in a bad value.
+                raise ValueError(repr((u, v)))  # FIXME this message sucks.
+    
+            (a, b), (c, d) = u, v
+            s = unify(a, c, s)
+            if s != False:
+                s = unify(b, d, s)
+    
+        return s
 
 .. code:: ipython2
 
@@ -1406,7 +1368,7 @@ of how many labels of each domain it has "seen".
             pass
     
         if not isinstance(f, tuple):
-            seen[f] = f.__class__(c[f.prefix])
+            seen[f] = f.__class__(c[f.prefix] + 1)
             c[f.prefix] += 1
             return seen[f]
     
@@ -1421,7 +1383,7 @@ of how many labels of each domain it has "seen".
 
 .. parsed-literal::
 
-    (((a0,), (a0, a0)), ((n0, n1), (n2,)))
+    (((a1,), (a1, a1)), ((n1, n2), (n3,)))
 
 
 
@@ -1544,7 +1506,7 @@ Rewrite the stack effect comments:
 
 .. parsed-literal::
 
-    ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+    ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
     cons = (a1 [.1.] -- [a1 .1.])
     divmod_ = (n2 n1 -- n4 n3)
     dup = (a1 -- a1 a1)
@@ -1561,13 +1523,13 @@ Rewrite the stack effect comments:
     rest = ([a1 .1.] -- [.1.])
     rolldown = (a1 a2 a3 -- a2 a3 a1)
     rollup = (a1 a2 a3 -- a3 a1 a2)
-    rrest = ([a0 a1 .0.] -- [.0.])
-    second = ([a0 a1 .0.] -- a1)
-    sqrt = (n0 -- n1)
+    rrest = ([a1 a2 .1.] -- [.1.])
+    second = ([a1 a2 .1.] -- a2)
+    sqrt = (n1 -- n2)
     succ = (n1 -- n2)
     swap = (a1 a2 -- a2 a1)
-    swons = ([.0.] a0 -- [a0 .0.])
-    third = ([a0 a1 a2 .0.] -- a2)
+    swons = ([.1.] a1 -- [a1 .1.])
+    third = ([a1 a2 a3 .1.] -- a3)
     tuck = (a2 a1 -- a1 a2 a1)
     uncons = ([a1 .1.] -- a1 [.1.])
 
@@ -1588,7 +1550,7 @@ Compose ``dup`` and ``mul``
 
 .. parsed-literal::
 
-    ((n0,), (n1,))
+    ((n1,), (n2,))
 
 
 
@@ -1604,7 +1566,7 @@ Revisit the ``F`` function, works fine.
 
 .. parsed-literal::
 
-    (((a0, (a1, s0)), a2, a3, a4), ((a3, (a2, s0)),))
+    (((a1, (a2, s1)), a3, a4, a5), ((a4, (a3, s1)),))
 
 
 
@@ -1615,7 +1577,7 @@ Revisit the ``F`` function, works fine.
 
 .. parsed-literal::
 
-    ([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])
+    ([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])
 
 
 Some otherwise inefficient functions are no longer to be feared. We can
@@ -1634,7 +1596,7 @@ also get the effect of combinators in some limited cases.
 
 .. parsed-literal::
 
-    (a0 a1 a2 -- a1 a0 a2)
+    (a1 a2 a3 -- a2 a1 a3)
 
 
 .. code:: ipython2
@@ -1645,7 +1607,7 @@ also get the effect of combinators in some limited cases.
 
 .. parsed-literal::
 
-    (a0 a1 a2 a3 -- a2 a3)
+    (a1 a2 a3 a4 -- a3 a4)
 
 
 .. code:: ipython2
@@ -1656,7 +1618,7 @@ also get the effect of combinators in some limited cases.
 
 .. parsed-literal::
 
-    (a0 a1 a2 -- a2 a1 a0)
+    (a1 a2 a3 -- a3 a2 a1)
 
 
 ``compile_()`` version 2
@@ -1689,9 +1651,9 @@ the ``compile_()`` function doesn't need to generate them anymore:
 .. parsed-literal::
 
     def F(stack):
-        """([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])"""
-        (a4, (a3, (a2, ((a0, (a1, s0)), stack)))) = stack
-        return ((a3, (a2, s0)), stack)
+        """([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])"""
+        (a5, (a4, (a3, ((a1, (a2, s1)), stack)))) = stack
+        return ((a4, (a3, s1)), stack)
 
 
 But it cannot magically create new functions that involve e.g. math and
@@ -1705,9 +1667,9 @@ such. Note that this is *not* a ``sqr`` function implementation:
 .. parsed-literal::
 
     def sqr(stack):
-        """(n0 -- n1)"""
-        (n0, stack) = stack
-        return (n1, stack)
+        """(n1 -- n2)"""
+        (n1, stack) = stack
+        return (n2, stack)
 
 
 (Eventually I should come back around to this becuase it's not tooo
@@ -1742,7 +1704,7 @@ comments. We can write a function to check that:
 
 .. parsed-literal::
 
-    ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+    ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
     cons = (a1 [.1.] -- [a1 .1.])
     dup = (a1 -- a1 a1)
     dupd = (a2 a1 -- a2 a2 a1)
@@ -1755,11 +1717,11 @@ comments. We can write a function to check that:
     rest = ([a1 .1.] -- [.1.])
     rolldown = (a1 a2 a3 -- a2 a3 a1)
     rollup = (a1 a2 a3 -- a3 a1 a2)
-    rrest = ([a0 a1 .0.] -- [.0.])
-    second = ([a0 a1 .0.] -- a1)
+    rrest = ([a1 a2 .1.] -- [.1.])
+    second = ([a1 a2 .1.] -- a2)
     swap = (a1 a2 -- a2 a1)
-    swons = ([.0.] a0 -- [a0 .0.])
-    third = ([a0 a1 a2 .0.] -- a2)
+    swons = ([.1.] a1 -- [a1 .1.])
+    third = ([a1 a2 a3 .1.] -- a3)
     tuck = (a2 a1 -- a1 a2 a1)
     uncons = ([a1 .1.] -- a1 [.1.])
 
@@ -1849,7 +1811,13 @@ It works.
 This function has to be modified to use the new datastructures and it is
 no longer recursive, instead recursion happens as part of unification.
 Further, the first and second of Pöial's rules are now handled
-automatically by the unification algorithm.
+automatically by the unification algorithm. (One easy way to see this is
+that now an empty stack effect comment is represented by a
+``StackJoyType`` instance which is not "falsey" and so neither of the
+first two rules' ``if`` clauses will ever be ``True``. Later on I change
+the "truthiness" of ``StackJoyType`` to false to let e.g.
+``joy.utils.stack.concat`` work with our stack effect comment cons-list
+tuples.)
 
 .. code:: ipython2
 
@@ -1886,20 +1854,20 @@ conversion function instead. This is programmer's laziness.
 
 .. parsed-literal::
 
-    ((a0, s0), (s0, (a0, (a0, s0))))
+    ((a1, s1), (s1, (a1, (a1, s1))))
 
 
 
 .. code:: ipython2
 
-    C(C(stack, uncons), uncons)
+    reduce(C, (stack, uncons, uncons))
 
 
 
 
 .. parsed-literal::
 
-    ((a0, (a1, s0)), (s0, (a1, (a0, (a0, (a1, s0))))))
+    ((a1, (a2, s1)), (s1, (a2, (a1, (a1, (a2, s1))))))
 
 
 
@@ -1966,7 +1934,7 @@ Clunky junk, but it will suffice for now.
 
 .. parsed-literal::
 
-    ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+    ccons = (a1 a2 [.1.] -- [a1 a2 .1.])
     cons = (a1 [.1.] -- [a1 .1.])
     divmod_ = (n2 n1 -- n4 n3)
     dup = (a1 -- a1 a1)
@@ -1983,15 +1951,15 @@ Clunky junk, but it will suffice for now.
     rest = ([a1 .1.] -- [.1.])
     rolldown = (a1 a2 a3 -- a2 a3 a1)
     rollup = (a1 a2 a3 -- a3 a1 a2)
-    rrest = ([a0 a1 .0.] -- [.0.])
-    second = ([a0 a1 .0.] -- a1)
-    sqrt = (n0 -- n1)
+    rrest = ([a1 a2 .1.] -- [.1.])
+    second = ([a1 a2 .1.] -- a2)
+    sqrt = (n1 -- n2)
     stack = (... -- ... [...])
     succ = (n1 -- n2)
     swaack = ([.1.] -- [.0.])
     swap = (a1 a2 -- a2 a1)
-    swons = ([.0.] a0 -- [a0 .0.])
-    third = ([a0 a1 a2 .0.] -- a2)
+    swons = ([.1.] a1 -- [a1 .1.])
+    third = ([a1 a2 a3 .1.] -- a3)
     tuck = (a2 a1 -- a1 a2 a1)
     uncons = ([a1 .1.] -- a1 [.1.])
 
@@ -2000,8 +1968,8 @@ Clunky junk, but it will suffice for now.
 
     print ; print doc_from_stack_effect(*stack)
     print ; print doc_from_stack_effect(*C(stack, uncons))
-    print ; print doc_from_stack_effect(*C(C(stack, uncons), uncons))
-    print ; print doc_from_stack_effect(*C(C(stack, uncons), cons))
+    print ; print doc_from_stack_effect(*reduce(C, (stack, uncons, uncons)))
+    print ; print doc_from_stack_effect(*reduce(C, (stack, uncons, cons)))
 
 
 .. parsed-literal::
@@ -2009,11 +1977,11 @@ Clunky junk, but it will suffice for now.
     
     (... -- ... [...])
     
-    (... a0 -- ... a0 a0 [...])
+    (... a1 -- ... a1 a1 [...])
     
-    (... a1 a0 -- ... a1 a0 a0 a1 [...])
+    (... a2 a1 -- ... a2 a1 a1 a2 [...])
     
-    (... a0 -- ... a0 [a0 ...])
+    (... a1 -- ... a1 [a1 ...])
 
 
 .. code:: ipython2
@@ -2023,7 +1991,7 @@ Clunky junk, but it will suffice for now.
 
 .. parsed-literal::
 
-    (... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])
+    (... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])
 
 
 .. code:: ipython2
@@ -2037,7 +2005,7 @@ Clunky junk, but it will suffice for now.
 
 .. parsed-literal::
 
-    ((s0, (a0, (a1, s1))), (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1)))
+    ((s1, (a1, (a2, s2))), (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2)))
 
 
 
@@ -2066,9 +2034,9 @@ comments are now already in the form needed for the Python code:
 .. parsed-literal::
 
     def Q(stack):
-        """(... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])"""
-        (s0, (a0, (a1, s1))) = stack
-        return (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1))
+        """(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])"""
+        (s1, (a1, (a2, s2))) = stack
+        return (((a2, (a1, s1)), s2), ((a2, (a1, s1)), s2))
 
 
 .. code:: ipython2
@@ -2103,7 +2071,7 @@ comments are now already in the form needed for the Python code:
 
 .. parsed-literal::
 
-    (a0 [.0.] -- a0)
+    (a1 [.1.] -- a1)
 
 
 .. code:: ipython2
@@ -2113,7 +2081,7 @@ comments are now already in the form needed for the Python code:
 
 .. parsed-literal::
 
-    (a0 [.0.] -- [[a0 .0.] .1.])
+    (a1 [.1.] -- [[a1 .1.] .2.])
 
 
 .. code:: ipython2
@@ -2125,7 +2093,7 @@ comments are now already in the form needed for the Python code:
 
 .. parsed-literal::
 
-    ((s0, (a0, s1)), (a0, s0))
+    ((s1, (a1, s2)), (a1, s1))
 
 
 
@@ -2177,8 +2145,8 @@ Part VI: Multiple Stack Effects
 
 .. parsed-literal::
 
-    (a1 -- a1 a1) (i1 i2 -- i3) (i0 -- i1)
-    (a1 -- a1 a1) (f1 f2 -- f3) (f0 -- f1)
+    (a1 -- a1 a1) (i1 i2 -- i3) (i1 -- i2)
+    (a1 -- a1 a1) (f1 f2 -- f3) (f1 -- f2)
 
 
 .. code:: ipython2
@@ -2199,25 +2167,25 @@ Part VI: Multiple Stack Effects
 
 .. code:: ipython2
 
-    for f in MC([dup], muls):
+    for f in MC([dup], [mul]):
         print doc_from_stack_effect(*f)
 
 
 .. parsed-literal::
 
-    (f0 -- f1)
-    (i0 -- i1)
+    (n1 -- n2)
 
 
 .. code:: ipython2
 
-    for f in MC([dup], [mul]):
+    for f in MC([dup], muls):
         print doc_from_stack_effect(*f)
 
 
 .. parsed-literal::
 
-    (n0 -- n1)
+    (f1 -- f2)
+    (i1 -- i2)
 
 
 Representing an Unbounded Sequence of Types
@@ -2541,8 +2509,8 @@ This function has to be modified to yield multiple results.
 
 .. parsed-literal::
 
-    (f0 -- f1)
-    (i0 -- i1)
+    (f1 -- f2)
+    (i1 -- i2)
 
 
 .. code:: ipython2
@@ -2555,7 +2523,7 @@ This function has to be modified to yield multiple results.
 
 .. parsed-literal::
 
-    ([n0* .0.] -- [n0* .0.] n0)
+    ([n1* .1.] -- [n1* .1.] n1)
 
 
 .. code:: ipython2
@@ -2568,8 +2536,8 @@ This function has to be modified to yield multiple results.
 
 .. parsed-literal::
 
-    (a0 [.0.] -- n0)
-    (n0 [n0* .0.] -- n1)
+    (a1 [.1.] -- n1)
+    (n1 [n1* .1.] -- n2)
 
 
 .. code:: ipython2
@@ -2584,7 +2552,7 @@ This function has to be modified to yield multiple results.
 
 .. parsed-literal::
 
-    (a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n0 [n0* .0.] -- n1)
+    (a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n1 [n1* .1.] -- n2)
 
 
 .. code:: ipython2
@@ -2828,6 +2796,19 @@ stack effect we have to "split universes" again and return both.
 
 .. code:: ipython2
 
+    expression
+
+
+
+
+.. parsed-literal::
+
+    (n1, (n2, (mul, ())))
+
+
+
+.. code:: ipython2
+
     infer(expression)
 
 
@@ -2835,74 +2816,97 @@ stack effect we have to "split universes" again and return both.
 
 .. parsed-literal::
 
-    []
+    [(s1, (f1, s1)), (s1, (i1, s1))]
 
 
 
 .. code:: ipython2
 
-    class SymbolJoyType(AnyJoyType):
-        prefix = 'F'
-    
-        def __init__(self, name, sec, number):
-            self.name = name
-            self.stack_effects = sec
-            self.number = number
-    
-    class CombinatorJoyType(SymbolJoyType): prefix = 'C'
-    
-    def dip_t(stack, expression):
-        (quote, (a1, stack)) = stack
-        expression = stack_concat(quote, (a1, expression))
-        return stack, expression
-    
-    CONS = SymbolJoyType('cons', [cons], 23)
-    DIP = CombinatorJoyType('dip', [dip_t], 44)
-    
-    
-    def kav(F, e):
-        #i, stack = F
-        if not e:
-            return [(F, e)]
-        n, e = e
-        if isinstance(n, SymbolJoyType):
-            Fs = []
-            for sec in n.stack_effects:
-                Fs.extend(MC([F], sec))
-            return [kav(Fn, e) for Fn in Fs]
-        if isinstance(n, CombinatorJoyType):
-            res = []
-            for f in n.stack_effects:
-                s, e = f(F[1], e)
-                new_F = F[0], s
-                res.extend(kav(new_F, e))
-            return res
-        lit = S[0], (n, S[0])
-        return [kav(Fn, e) for Fn in MC([F], [lit])]
+    infer(expression)
+
+
+
+
+.. parsed-literal::
+
+    [(s1, (f1, s1)), (s1, (i1, s1))]
 
 
-compare, and be amazed:
 
 .. code:: ipython2
 
-    def dip_t(stack, expression):
-        (quote, (a1, stack)) = stack
-        expression = stack_concat(quote, (a1, expression))
-        return stack, expression
+    for stack_effect_comment in infer(expression):
+        print doc_from_stack_effect(*stack_effect_comment)
+
+
+.. parsed-literal::
+
+    (-- f1)
+    (-- i1)
+
+
+.. code:: ipython2
+
+    expression
+
+
+
+
+.. parsed-literal::
+
+    (n1, (n2, (mul, ())))
+
+
 
 .. code:: ipython2
 
-    def dip(stack, expression, dictionary):
-        (quote, (x, stack)) = stack
-        expression = (x, expression)
-        return stack, concat(quote, expression), dictionary
+    infer(expression)
+
+
+
+
+.. parsed-literal::
+
+    [(s1, (f1, s1)), (s1, (i1, s1))]
+
+
 
 And that brings us to current Work-In-Progress. I'm pretty hopeful that
-the mixed-mode inferencer/interpreter ``kav()`` function along with the
-ability to specify multiple implementations for the combinators will
+the mixed-mode inferencer/interpreter ``infer()`` function along with
+the ability to specify multiple implementations for the combinators will
 permit modelling of the stack effects of e.g. ``ifte``. If I can keep up
 the pace I should be able to verify that conjecture by the end of June.
 
+Conclusion
+----------
+
+(for now...)
+
+Work remains to be done:
+
+-  the rest of the library has to be covered
+-  figure out how to deal with ``loop`` and ``genrec``, etc..
+-  extend the types to check values (see the appendix)
+-  other kinds of "higher order" type variables, OR, AND, etc..
+-  maybe rewrite in Prolog for great good?
+-  definitions
+-  don't permit composition of functions that don't compose
+-  auto-compile compilable functions
+-  Compiling more than just the Yin functions.
+-  getting better visibility (than Python debugger.)
+-  DOOOOCS!!!! Lots of docs!
+-  docstrings all around
+-  improve this notebook (it kinda falls apart at the end narratively. I
+   went off and just started writing code to see if it would work. It
+   does, but now I have to come back and describe here what I did.
+
+I'm starting to realize that, with the inferencer/checker/compiler
+coming along, and with the UI ready to be rewritten in Joy, I'm close to
+a time when my ephasis is going to have to shift from crunchy code stuff
+to squishy human stuff. I'm going to have to put normal people in front
+of this and see if, in fact, they *can* learn the basics of programming
+with it.
+
 The rest of this stuff is junk and/or unfinished material.
 
 Appendix: Joy in the Logical Paradigm
@@ -2914,143 +2918,168 @@ For this to work the type label classes have to be modified to let
 
 .. code:: ipython2
 
-    F = reduce(C, (pop, swap, rolldown, rest, rest, cons, cons))
+    def _ge(self, other):
+        return (issubclass(other.__class__, self.__class__)
+                or hasattr(self, 'accept')
+                and isinstance(other, self.accept))
     
-    print doc_from_stack_effect(*F)
+    AnyJoyType.__ge__ = _ge
+    AnyJoyType.accept = tuple, int, float, long, str, unicode, bool, Symbol
+    StackJoyType.accept = tuple
 
+.. code:: ipython2
 
-::
+    F = infer(l2s((pop, swap, rolldown, rest, rest, cons, cons)))
+    
+    for f in F:
+        print doc_from_stack_effect(*f)
 
 
-    ---------------------------------------------------------------------------
+.. parsed-literal::
 
-    TypeError                                 Traceback (most recent call last)
+    ([a4 a5 .1.] a3 a2 a1 -- [a2 a3 .1.])
 
-    <ipython-input-119-7fde90b4e88f> in <module>()
-          1 F = reduce(C, (pop, swap, rolldown, rest, rest, cons, cons))
-          2 
-    ----> 3 print doc_from_stack_effect(*F)
-    
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
+.. code:: ipython2
 
+    from joy.parser import text_to_expression
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+.. code:: ipython2
 
+    F = infer(l2s((pop, pop, pop)))
+    
+    for f in F:
+        print doc_from_stack_effect(*f)
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
+.. parsed-literal::
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+    (a3 a2 a1 --)
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
+.. code:: ipython2
 
+    s = text_to_expression('0 1 2')
+    s
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
+.. parsed-literal::
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+    (0, (1, (2, ())))
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
+.. code:: ipython2
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+    F[0][0]
 
 
-    <ipython-input-98-ddee30dbb1a6> in C(f, g)
-         10 def C(f, g):
-         11     f, g = relabel(f, g)
-    ---> 12     for fg in compose(f, g):
-         13         yield delabel(fg)
 
 
-    <ipython-input-97-5eb7ac5ad2c2> in compose(f, g)
-          1 def compose(f, g):
-    ----> 2     (f_in, f_out), (g_in, g_out) = f, g
-          3     s = unify(g_in, f_out)
-          4     if not s:
-          5         raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
+.. parsed-literal::
 
+    (a1, (a2, (a3, s1)))
 
-    TypeError: 'SymbolJoyType' object is not iterable
 
 
 .. code:: ipython2
 
-    from joy.parser import text_to_expression
+    L = unify(s, F[0][0])
+    L
+
+
+
+
+.. parsed-literal::
+
+    ()
+
+
 
 .. code:: ipython2
 
-    s = text_to_expression('[3 4 ...] 2 1')
+    s = text_to_expression('0 1 2 [3 4]')
     s
 
+
+
+
+.. parsed-literal::
+
+    (0, (1, (2, ((3, (4, ())), ()))))
+
+
+
 .. code:: ipython2
 
-    L = unify(F[1], s)
+    F[0][0]
+
+
+
+
+.. parsed-literal::
+
+    (a1, (a2, (a3, s1)))
+
+
+
+.. code:: ipython2
+
+    L = unify(s, F[0][0])
     L
 
+
+
+
+.. parsed-literal::
+
+    ()
+
+
+
 .. code:: ipython2
 
-    F[1]
+    L = unify(F[0][0], s)
+    L
+
+
+
+
+.. parsed-literal::
+
+    ()
+
+
 
 .. code:: ipython2
 
     F[1][0]
 
+
+::
+
+
+    ---------------------------------------------------------------------------
+
+    IndexError                                Traceback (most recent call last)
+
+    <ipython-input-133-58a8e44e9cba> in <module>()
+    ----> 1 F[1][0]
+    
+
+    IndexError: list index out of range
+
+
 .. code:: ipython2
 
     s[0]
 
+.. code:: ipython2
+
+    A[1] >= 23
+
 `Abstract Interpretation <https://en.wikipedia.org/wiki/Abstract_interpretation>`__
 -----------------------------------------------------------------------------------
 
index 194c0c6..a1d3435 100644 (file)
@@ -53,18 +53,17 @@ class TestCombinators(TestMixin, unittest.TestCase):
       ]
     self.assertEqualTypeStructure(infr(expression), f)
 
-  def test_cons_dip(self):
-    expression = (cons, s0), dip  # [cons] dip
-    # (a2 [...1] a1 -- [a2 ...1] a3)
-    f =  (a1, (s1, (a2, s2))), (a1, ((a2, s1), s2))
-    # shouldn't a3 be a1?
-    self.assertEqualTypeStructure(infr(expression), [f])
-
   def test_dip(self):
     expression = dip,
     f = ((s1, (a1, s2)), (a2, s2))  # (a1 [...1] -- a2)
     self.assertEqualTypeStructure(infr(expression), [f])
 
+  def test_cons_dip(self):
+    expression = (cons, s0), dip  # [cons] dip
+    # (a2 [...1] a1 -- [a2 ...1] a1)
+    f =  (a1, (s1, (a2, s2))), (a1, ((a2, s1), s2))
+    self.assertEqualTypeStructure(infr(expression), [f])
+
   def test_cons_dipd(self):
     expression = a1, a3, (cons, s0), dipd
     f = ((s0, (a0, s1)), (a1, (a2, ((a0, s0), s1))))
@@ -169,4 +168,4 @@ class TestYin(TestMixin, unittest.TestCase):
 
 
 if __name__ == '__main__':
-    unittest.main(defaultTest='TestCombinators.test_cons_dip')
+    unittest.main()