2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5 <html xmlns="http://www.w3.org/1999/xhtml">
7 <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
8 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9 <title>The Blissful Elegance of Typing Joy — Thun 0.4.1 documentation</title>
10 <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
11 <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12 <script type="text/javascript" src="../_static/documentation_options.js"></script>
13 <script type="text/javascript" src="../_static/jquery.js"></script>
14 <script type="text/javascript" src="../_static/underscore.js"></script>
15 <script type="text/javascript" src="../_static/doctools.js"></script>
16 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
17 <link rel="index" title="Index" href="../genindex.html" />
18 <link rel="search" title="Search" href="../search.html" />
19 <link rel="next" title="Type Checking" href="TypeChecking.html" />
20 <link rel="prev" title="Traversing Datastructures with Zippers" href="Zipper.html" />
22 <link rel="stylesheet" href="../_static/custom.css" type="text/css" />
25 <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
30 <div class="document">
31 <div class="documentwrapper">
32 <div class="bodywrapper">
33 <div class="body" role="main">
35 <div class="section" id="the-blissful-elegance-of-typing-joy">
36 <h1>The Blissful Elegance of Typing Joy<a class="headerlink" href="#the-blissful-elegance-of-typing-joy" title="Permalink to this headline">¶</a></h1>
37 <p>This notebook presents a simple type inferencer for Joy code. It can
38 infer the stack effect of most Joy expressions. It’s built largely by
39 means of existing ideas and research. (A great overview of the existing
40 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
42 given by Rob Kleffner on or about 2017-03-10 as part of a course on the
43 history of programming languages.)</p>
44 <p>The notebook starts with a simple inferencer based on the work of Jaanus
45 Pöial which we then progressively elaborate to cover more Joy semantics.
46 Along the way we write a simple “compiler” that emits Python code for
47 what I like to call Yin functions. (Yin functions are those that only
48 rearrange values in stacks, as opposed to Yang functions that actually
49 work on the values themselves.)</p>
50 <div class="section" id="part-i-poials-rules">
51 <h2>Part I: Pöial’s Rules<a class="headerlink" href="#part-i-poials-rules" title="Permalink to this headline">¶</a></h2>
52 <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
54 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@INPROCEEDINGS</span><span class="p">{</span><span class="n">Pöial06typingtools</span><span class="p">,</span>
55 <span class="n">author</span> <span class="o">=</span> <span class="p">{</span><span class="n">Jaanus</span> <span class="n">Pöial</span><span class="p">},</span>
56 <span class="n">title</span> <span class="o">=</span> <span class="p">{</span><span class="n">Typing</span> <span class="n">tools</span> <span class="k">for</span> <span class="n">typeless</span> <span class="n">stack</span> <span class="n">languages</span><span class="p">},</span>
57 <span class="n">booktitle</span> <span class="o">=</span> <span class="p">{</span><span class="n">In</span> <span class="mi">23</span><span class="n">rd</span> <span class="n">Euro</span><span class="o">-</span><span class="n">Forth</span> <span class="n">Conference</span><span class="p">},</span>
58 <span class="n">year</span> <span class="o">=</span> <span class="p">{</span><span class="mi">2006</span><span class="p">},</span>
59 <span class="n">pages</span> <span class="o">=</span> <span class="p">{</span><span class="mi">40</span><span class="o">--</span><span class="mi">46</span><span class="p">}</span>
60 <span class="p">}</span>
63 <div class="section" id="first-rule">
64 <h3>First Rule<a class="headerlink" href="#first-rule" title="Permalink to this headline">¶</a></h3>
65 <p>This rule deals with functions (and literals) that put items on the
66 stack <code class="docutils literal notranslate"><span class="pre">(--</span> <span class="pre">d)</span></code>:</p>
67 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> (a -- b)∘(-- d)
73 <div class="section" id="second-rule">
74 <h3>Second Rule<a class="headerlink" href="#second-rule" title="Permalink to this headline">¶</a></h3>
75 <p>This rule deals with functions that consume items from the stack
76 <code class="docutils literal notranslate"><span class="pre">(a</span> <span class="pre">--)</span></code>:</p>
77 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> (a --)∘(c -- d)
83 <div class="section" id="third-rule">
84 <h3>Third Rule<a class="headerlink" href="#third-rule" title="Permalink to this headline">¶</a></h3>
85 <p>The third rule is actually two rules. These two rules deal with
86 composing functions when the second one will consume one of items the
87 first one produces. The two types must be
88 <a class="reference external" href="https://en.wikipedia.org/wiki/Robinson's_unification_algorithm">unified</a>
89 or a type conflict declared.</p>
90 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
91 -------------------------------
92 (a -- b )∘(c -- d) t[i] == t[k] == u[j]
95 (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
96 -------------------------------
97 (a -- b )∘(c -- d) t[i] == u[k] == u[j]
100 <p>Let’s work through some examples by hand to develop an intuition for the
102 <p>There’s a function in one of the other notebooks.</p>
103 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">==</span> <span class="n">pop</span> <span class="n">swap</span> <span class="n">roll</span><span class="o"><</span> <span class="n">rest</span> <span class="n">rest</span> <span class="n">cons</span> <span class="n">cons</span>
106 <p>It’s all “stack chatter” and list manipulation so we should be able to
109 <div class="section" id="stack-effect-comments">
110 <h3>Stack Effect Comments<a class="headerlink" href="#stack-effect-comments" title="Permalink to this headline">¶</a></h3>
111 <p>Joy function types will be represented by Forth-style stack effect
112 comments. I’m going to use numbers instead of names to keep track of the
113 stack arguments. (A little bit like <a class="reference external" href="https://en.wikipedia.org/wiki/De_Bruijn_index">De Bruijn
114 index</a>, at least it
115 reminds me of them):</p>
116 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pop</span> <span class="p">(</span><span class="mi">1</span> <span class="o">--</span><span class="p">)</span>
118 <span class="n">swap</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
120 <span class="n">roll</span><span class="o"><</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span><span class="p">)</span>
123 <p>These commands alter the stack but don’t “look at” the values so these
124 numbers represent an “Any type”.</p>
126 <div class="section" id="pop-swap">
127 <h3><code class="docutils literal notranslate"><span class="pre">pop</span> <span class="pre">swap</span></code><a class="headerlink" href="#pop-swap" title="Permalink to this headline">¶</a></h3>
128 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="o">--</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
131 <p>Here we encounter a complication. The argument numbers need to be made
132 unique among both sides. For this let’s change <code class="docutils literal notranslate"><span class="pre">pop</span></code> to use 0:</p>
133 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">0</span> <span class="o">--</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
136 <p>Following the second rule:</p>
137 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
141 <div class="section" id="popswap-roll">
142 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap</span> <span class="pre">roll<</span></code><a class="headerlink" href="#popswap-roll" title="Permalink to this headline">¶</a></h3>
143 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span><span class="p">)</span>
146 <p>Let’s re-label them:</p>
147 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="n">a</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">1</span><span class="n">a</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
150 <p>Now we follow the rules.</p>
151 <p>We must unify <code class="docutils literal notranslate"><span class="pre">1a</span></code> and <code class="docutils literal notranslate"><span class="pre">3b</span></code>, and <code class="docutils literal notranslate"><span class="pre">2a</span></code> and <code class="docutils literal notranslate"><span class="pre">2b</span></code>, replacing the
152 terms in the forms:</p>
153 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="n">a</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">1</span><span class="n">a</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
154 <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="mi">1</span><span class="n">a</span><span class="p">:</span> <span class="mi">3</span><span class="n">b</span><span class="p">}</span>
155 <span class="p">(</span><span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">a</span> <span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
156 <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="mi">2</span><span class="n">a</span><span class="p">:</span> <span class="mi">2</span><span class="n">b</span><span class="p">}</span>
157 <span class="p">(</span><span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
160 <p>Here we must apply the second rule:</p>
161 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">(</span><span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
162 <span class="o">-----------------------------------</span>
163 <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
166 <p>Now we de-label the type, uh, labels:</p>
167 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
169 <span class="n">w</span><span class="o">/</span> <span class="p">{</span>
170 <span class="mi">1</span><span class="n">b</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
171 <span class="mi">3</span><span class="n">b</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
172 <span class="mi">2</span><span class="n">b</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
173 <span class="mi">0</span><span class="n">a</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
174 <span class="p">}</span>
176 <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
179 <p>And now we have the stack effect comment for <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<</span></code>.</p>
181 <div class="section" id="compiling-popswaproll">
182 <h3>Compiling <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<</span></code><a class="headerlink" href="#compiling-popswaproll" title="Permalink to this headline">¶</a></h3>
183 <p>The simplest way to “compile” this function would be something like:</p>
184 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
185 <span class="k">return</span> <span class="n">rolldown</span><span class="p">(</span><span class="o">*</span><span class="n">swap</span><span class="p">(</span><span class="o">*</span><span class="n">pop</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">)))</span>
188 <p>However, internally this function would still be allocating tuples
189 (stack cells) and doing other unnecesssary work.</p>
190 <p>Looking ahead for a moment, from the stack effect comment:</p>
191 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
194 <p>We should be able to directly write out a Python function like:</p>
195 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
196 <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</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">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
197 <span class="k">return</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
200 <p>This eliminates the internal work of the first version. Because this
201 function only rearranges the stack and doesn’t do any actual processing
202 on the stack items themselves all the information needed to implement it
203 is in the stack effect comment.</p>
205 <div class="section" id="functions-on-stacks">
206 <h3>Functions on Stacks<a class="headerlink" href="#functions-on-stacks" title="Permalink to this headline">¶</a></h3>
207 <p>These are slightly tricky.</p>
208 <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>
210 <span class="n">cons</span> <span class="p">(</span> <span class="mi">1</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">1</span> <span class="o">...</span><span class="p">]</span> <span class="p">)</span>
214 <div class="section" id="popswaproll-rest">
215 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<</span> <span class="pre">rest</span></code><a class="headerlink" href="#popswaproll-rest" title="Permalink to this headline">¶</a></h3>
216 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</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>
219 <p>Re-label (instead of adding left and right tags I’m just taking the next
220 available index number for the right-side stack effect comment):</p>
221 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span> <span class="p">([</span><span class="mi">4</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>
224 <p>Unify and update:</p>
225 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span> <span class="p">([</span><span class="mi">4</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>
226 <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="mi">1</span><span class="p">:</span> <span class="p">[</span><span class="mi">4</span> <span class="o">...</span><span class="p">]}</span>
227 <span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">)</span> <span class="p">(</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
230 <p>Apply the first rule:</p>
231 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span><span class="p">)</span> <span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
232 <span class="o">---------------------------------------</span>
233 <span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
236 <p>And there we are.</p>
238 <div class="section" id="popswaproll-rest-rest">
239 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest</span> <span class="pre">rest</span></code><a class="headerlink" href="#popswaproll-rest-rest" title="Permalink to this headline">¶</a></h3>
240 <p>Let’s do it again.</p>
241 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">...</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>
244 <p>Re-label (the tails of the lists on each side each get their own label):</p>
245 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span> <span class="p">([</span><span class="mi">5</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>
248 <p>Unify and update (note the opening square brackets have been omited in
249 the substitution dict, this is deliberate and I’ll explain below):</p>
250 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="p">)</span> <span class="p">([</span><span class="mi">5</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>
251 <span class="n">w</span><span class="o">/</span> <span class="p">{</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="p">:</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">}</span>
252 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">([</span><span class="mi">5</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>
255 <p>How do we find <code class="docutils literal notranslate"><span class="pre">.0.]</span></code> in <code class="docutils literal notranslate"><span class="pre">[4</span> <span class="pre">.0.]</span></code> and replace it with <code class="docutils literal notranslate"><span class="pre">5</span> <span class="pre">.1.]</span></code>
256 getting the result <code class="docutils literal notranslate"><span class="pre">[4</span> <span class="pre">5</span> <span class="pre">.1.]</span></code>? This might seem hard, but because the
257 underlying structure of the Joy list is a cons-list in Python it’s
258 actually pretty easy. I’ll explain below.</p>
259 <p>Next we unify and find our two terms are the same already: <code class="docutils literal notranslate"><span class="pre">[5</span> <span class="pre">.1.]</span></code>:</p>
260 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">([</span><span class="mi">5</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>
264 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span><span class="p">)</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>
267 <p>From here we apply the first rule and get:</p>
268 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
271 <p>Cleaning up the labels:</p>
272 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
275 <p>This is the stack effect of <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest∘rest</span></code>.</p>
277 <div class="section" id="popswaproll-restrest-cons">
278 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest∘rest</span> <span class="pre">cons</span></code><a class="headerlink" href="#popswaproll-restrest-cons" title="Permalink to this headline">¶</a></h3>
279 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span> <span class="p">(</span><span class="mi">1</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">1</span> <span class="o">...</span><span class="p">])</span>
283 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">(</span><span class="mi">6</span> <span class="p">[</span><span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
287 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">(</span><span class="mi">6</span> <span class="p">[</span><span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
288 <span class="n">w</span><span class="o">/</span> <span class="p">{</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">:</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="p">}</span>
289 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">)</span> <span class="p">(</span><span class="mi">6</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
290 <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="mi">2</span><span class="p">:</span> <span class="mi">6</span><span class="p">}</span>
291 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="mi">6</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">)</span> <span class="p">(</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
295 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="mi">6</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
299 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">2</span> <span class="o">...</span><span class="p">])</span>
304 <div class="section" id="popswaproll-restrestcons-cons">
305 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest∘rest∘cons</span> <span class="pre">cons</span></code><a class="headerlink" href="#popswaproll-restrestcons-cons" title="Permalink to this headline">¶</a></h3>
306 <p>One more time.</p>
307 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">2</span> <span class="o">...</span><span class="p">])</span> <span class="p">(</span><span class="mi">1</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">1</span> <span class="o">...</span><span class="p">])</span>
311 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">(</span><span class="mi">6</span> <span class="p">[</span><span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
315 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">(</span><span class="mi">6</span> <span class="p">[</span><span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="p">)</span>
316 <span class="n">w</span><span class="o">/</span> <span class="p">{</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="p">:</span> <span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">}</span>
317 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">)</span> <span class="p">(</span><span class="mi">6</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
318 <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="mi">3</span><span class="p">:</span> <span class="mi">6</span><span class="p">}</span>
319 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">6</span> <span class="mi">1</span> <span class="o">--</span> <span class="p">)</span> <span class="p">(</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
322 <p>First or second rule:</p>
323 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">6</span> <span class="mi">1</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
326 <p>Clean up the labels:</p>
327 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">])</span>
330 <p>And there you have it, the stack effect for
331 <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest∘rest∘cons∘cons</span></code>.</p>
332 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">])</span>
335 <p>From this stack effect comment it should be possible to construct the
336 following Python code:</p>
337 <div class="code ipython2 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>
338 <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</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>
339 <span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
344 <div class="section" id="part-ii-implementation">
345 <h2>Part II: Implementation<a class="headerlink" href="#part-ii-implementation" title="Permalink to this headline">¶</a></h2>
346 <div class="section" id="representing-stack-effect-comments-in-python">
347 <h3>Representing Stack Effect Comments in Python<a class="headerlink" href="#representing-stack-effect-comments-in-python" title="Permalink to this headline">¶</a></h3>
348 <p>I’m going to use pairs of tuples of type descriptors, which will be
349 integers or tuples of type descriptors:</p>
350 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">roll_dn</span> <span class="o">=</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="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
352 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()</span>
354 <span class="n">swap</span> <span class="o">=</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="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
358 <div class="section" id="compose">
359 <h3><code class="docutils literal notranslate"><span class="pre">compose()</span></code><a class="headerlink" href="#compose" title="Permalink to this headline">¶</a></h3>
360 <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>
362 <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>
364 <span class="c1"># First rule.</span>
365 <span class="c1">#</span>
366 <span class="c1"># (a -- b) (-- d)</span>
367 <span class="c1"># ---------------------</span>
368 <span class="c1"># (a -- b d)</span>
370 <span class="k">if</span> <span class="ow">not</span> <span class="n">g_in</span><span class="p">:</span>
372 <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span> <span class="o">=</span> <span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span> <span class="o">+</span> <span class="n">g_out</span>
374 <span class="c1"># Second rule.</span>
375 <span class="c1">#</span>
376 <span class="c1"># (a --) (c -- d)</span>
377 <span class="c1"># ---------------------</span>
378 <span class="c1"># (c a -- d)</span>
380 <span class="k">elif</span> <span class="ow">not</span> <span class="n">f_out</span><span class="p">:</span>
382 <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span> <span class="o">=</span> <span class="n">g_in</span> <span class="o">+</span> <span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span>
384 <span class="k">else</span><span class="p">:</span> <span class="c1"># Unify, update, recur.</span>
386 <span class="n">fo</span><span class="p">,</span> <span class="n">gi</span> <span class="o">=</span> <span class="n">f_out</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">g_in</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
388 <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">gi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
390 <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"># s can also be the empty dict, which is ok.</span>
391 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.'</span> <span class="o">%</span> <span class="p">(</span><span class="n">fo</span><span class="p">,</span> <span class="n">gi</span><span class="p">))</span>
393 <span class="n">f_g</span> <span class="o">=</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="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">g_out</span><span class="p">)</span>
395 <span class="k">if</span> <span class="n">s</span><span class="p">:</span> <span class="n">f_g</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">f_g</span><span class="p">)</span>
397 <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span> <span class="o">=</span> <span class="n">compose</span><span class="p">(</span><span class="o">*</span><span class="n">f_g</span><span class="p">)</span>
399 <span class="k">return</span> <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span>
403 <div class="section" id="unify">
404 <h3><code class="docutils literal notranslate"><span class="pre">unify()</span></code><a class="headerlink" href="#unify" title="Permalink to this headline">¶</a></h3>
405 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</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="kc">None</span><span class="p">):</span>
406 <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
407 <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
409 <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>
410 <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>
411 <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>
412 <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>
413 <span class="k">else</span><span class="p">:</span>
414 <span class="n">s</span> <span class="o">=</span> <span class="kc">False</span>
416 <span class="k">return</span> <span class="n">s</span>
420 <div class="section" id="update">
421 <h3><code class="docutils literal notranslate"><span class="pre">update()</span></code><a class="headerlink" href="#update" title="Permalink to this headline">¶</a></h3>
422 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">term</span><span class="p">):</span>
423 <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
424 <span class="k">return</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">term</span><span class="p">)</span>
425 <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">inner</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">term</span><span class="p">)</span>
429 <div class="section" id="relabel">
430 <h3><code class="docutils literal notranslate"><span class="pre">relabel()</span></code><a class="headerlink" href="#relabel" title="Permalink to this headline">¶</a></h3>
431 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">relabel</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
432 <span class="k">return</span> <span class="n">left</span><span class="p">,</span> <span class="n">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">)</span>
434 <span class="k">def</span> <span class="nf">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">):</span>
435 <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">right</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
436 <span class="k">return</span> <span class="mi">1000</span> <span class="o">+</span> <span class="n">right</span>
437 <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_1000</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">right</span><span class="p">)</span>
439 <span class="n">relabel</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
442 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()),</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="p">(</span><span class="mi">1002</span><span class="p">,</span> <span class="mi">1001</span><span class="p">)))</span>
446 <div class="section" id="delabel">
447 <h3><code class="docutils literal notranslate"><span class="pre">delabel()</span></code><a class="headerlink" href="#delabel" title="Permalink to this headline">¶</a></h3>
448 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
449 <span class="n">s</span> <span class="o">=</span> <span class="p">{</span><span class="n">u</span><span class="p">:</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">u</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">_unique</span><span class="p">(</span><span class="n">f</span><span class="p">)))}</span>
450 <span class="k">return</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
452 <span class="k">def</span> <span class="nf">_unique</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">seen</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
453 <span class="k">if</span> <span class="n">seen</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
454 <span class="n">seen</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
455 <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>
456 <span class="n">seen</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
457 <span class="k">else</span><span class="p">:</span>
458 <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
459 <span class="n">_unique</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">seen</span><span class="p">)</span>
460 <span class="k">return</span> <span class="n">seen</span>
462 <span class="n">delabel</span><span class="p">(</span><span class="n">relabel</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">))</span>
465 <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="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>
469 <div class="section" id="c">
470 <h3><code class="docutils literal notranslate"><span class="pre">C()</span></code><a class="headerlink" href="#c" title="Permalink to this headline">¶</a></h3>
471 <p>At last we put it all together in a function <code class="docutils literal notranslate"><span class="pre">C()</span></code> that accepts two
472 stack effect comments and returns their composition (or raises and
473 exception if they can’t be composed due to type conflicts.)</p>
474 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></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>
475 <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>
476 <span class="n">fg</span> <span class="o">=</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>
477 <span class="k">return</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
480 <p>Let’s try it out.</p>
481 <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">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
484 <div class="highlight-default notranslate"><div class="highlight"><pre><span></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="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
487 <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">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">),</span> <span class="n">roll_dn</span><span class="p">)</span>
490 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</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="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
493 <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">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">)</span>
496 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</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="mi">2</span><span class="p">))</span>
499 <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">pop</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
502 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</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="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
505 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">poswrd</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">roll_dn</span><span class="p">))</span>
506 <span class="n">poswrd</span>
509 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</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="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
513 <div class="section" id="stack-functions">
514 <h3>Stack Functions<a class="headerlink" href="#stack-functions" title="Permalink to this headline">¶</a></h3>
515 <p>Here’s that trick to represent functions like <code class="docutils literal notranslate"><span class="pre">rest</span></code> and <code class="docutils literal notranslate"><span class="pre">cons</span></code> that
516 manipulate stacks. We use a cons-list of tuples and give the tails their
517 own numbers. Then everything above already works.</p>
518 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rest</span> <span class="o">=</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="p">(</span><span class="mi">2</span><span class="p">,)</span>
520 <span class="n">cons</span> <span class="o">=</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="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),)</span>
523 <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">poswrd</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
526 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</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="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">))</span>
529 <p>Compare this to the stack effect comment we wrote above:</p>
530 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</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="mi">0</span> <span class="p">),</span> <span class="p">(</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span> <span class="p">))</span>
531 <span class="p">(</span> <span class="p">[</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
534 <p>The translation table, if you will, would be:</p>
535 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
536 <span class="mi">3</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
537 <span class="mi">4</span><span class="p">:</span> <span class="o">...</span><span class="p">],</span>
538 <span class="mi">1</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
539 <span class="mi">2</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
540 <span class="mi">0</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
541 <span class="p">}</span>
544 <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">roll_dn</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>
546 <span class="n">F</span>
549 <div class="highlight-default notranslate"><div class="highlight"><pre><span></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="mi">5</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="mi">0</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">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),))</span>
552 <p>Compare with the stack effect comment and you can see it works fine:</p>
553 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">])</span>
554 <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">0</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">5</span>
558 <div class="section" id="dealing-with-cons-and-uncons">
559 <h3>Dealing with <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code><a class="headerlink" href="#dealing-with-cons-and-uncons" title="Permalink to this headline">¶</a></h3>
560 <p>However, if we try to compose e.g. <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code> it won’t
562 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">uncons</span> <span class="o">=</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="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
565 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
566 <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>
567 <span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
568 <span class="nb">print</span> <span class="n">e</span>
571 <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>
574 <div class="section" id="unify-version-2">
575 <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>
576 <p>The problem is that the <code class="docutils literal notranslate"><span class="pre">unify()</span></code> function as written doesn’t handle
577 the case when both terms are tuples. We just have to add a clause to
578 deal with this recursively:</p>
579 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</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="kc">None</span><span class="p">):</span>
580 <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
581 <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
582 <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
583 <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>
584 <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>
586 <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>
587 <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>
589 <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>
590 <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>
592 <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>
594 <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>
595 <span class="c1"># Not a type error, caller passed in a bad value.</span>
596 <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>
598 <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>
599 <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>
600 <span class="k">if</span> <span class="n">s</span> <span class="o">!=</span> <span class="kc">False</span><span class="p">:</span>
601 <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>
602 <span class="k">else</span><span class="p">:</span>
603 <span class="n">s</span> <span class="o">=</span> <span class="kc">False</span>
605 <span class="k">return</span> <span class="n">s</span>
608 <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>
611 <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="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
617 <div class="section" id="part-iii-compiling-yin-functions">
618 <h2>Part III: Compiling Yin Functions<a class="headerlink" href="#part-iii-compiling-yin-functions" title="Permalink to this headline">¶</a></h2>
619 <p>Now consider the Python function we would like to derive:</p>
620 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
621 <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</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>
622 <span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
625 <p>And compare it to the input stack effect comment tuple we just computed:</p>
626 <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>
629 <div class="highlight-default notranslate"><div class="highlight"><pre><span></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="mi">5</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="mi">0</span><span class="p">)</span>
632 <p>The stack-de-structuring tuple has nearly the same form as our input
633 stack effect comment tuple, just in the reverse order:</p>
634 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span>
637 <p>Remove the punctuation:</p>
638 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">_</span> <span class="n">d</span> <span class="n">c</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">))</span>
641 <p>Reverse the order and compare:</p>
642 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">))</span> <span class="n">c</span> <span class="n">d</span> <span class="n">_</span>
643 <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="mi">5</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="mi">0</span><span class="p">)</span>
647 <p>And the return tuple</p>
648 <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>
651 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),)</span>
654 <p>is similar to the output stack effect comment tuple:</p>
655 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
656 <span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span> <span class="p">)),</span> <span class="p">)</span>
659 <p>This should make it pretty easy to write a Python function that accepts
660 the stack effect comment tuples and returns a new Python function
661 (either as a string of code or a function object ready to use) that
662 performs the semantics of that Joy function (described by the stack
664 <div class="section" id="python-identifiers">
665 <h3>Python Identifiers<a class="headerlink" href="#python-identifiers" title="Permalink to this headline">¶</a></h3>
666 <p>We want to substitute Python identifiers for the integers. I’m going to
667 repurpose <code class="docutils literal notranslate"><span class="pre">joy.parser.Symbol</span></code> class for this:</p>
668 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">defaultdict</span>
669 <span class="kn">from</span> <span class="nn">joy.parser</span> <span class="k">import</span> <span class="n">Symbol</span>
672 <span class="k">def</span> <span class="nf">_names_for</span><span class="p">():</span>
673 <span class="n">I</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">xrange</span><span class="p">(</span><span class="mi">1000</span><span class="p">))</span>
674 <span class="k">return</span> <span class="k">lambda</span><span class="p">:</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'a</span><span class="si">%i</span><span class="s1">'</span> <span class="o">%</span> <span class="nb">next</span><span class="p">(</span><span class="n">I</span><span class="p">))</span>
677 <span class="k">def</span> <span class="nf">identifiers</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
678 <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
679 <span class="n">s</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">_names_for</span><span class="p">())</span>
680 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
681 <span class="k">return</span> <span class="n">s</span><span class="p">[</span><span class="n">term</span><span class="p">]</span>
682 <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">identifiers</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">term</span><span class="p">)</span>
686 <div class="section" id="doc-from-stack-effect">
687 <h3><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code><a class="headerlink" href="#doc-from-stack-effect" title="Permalink to this headline">¶</a></h3>
688 <p>As a convenience I’ve implemented a function to convert the Python stack
689 effect comment tuples to reasonable text format. There are some details
690 in how this code works that related to stuff later in the notebook, so
691 you should skip it for now and read it later if you’re interested.</p>
692 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
693 <span class="k">return</span> <span class="s1">'(</span><span class="si">%s</span><span class="s1">--</span><span class="si">%s</span><span class="s1">)'</span> <span class="o">%</span> <span class="p">(</span>
694 <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">_to_str</span><span class="p">,</span> <span class="n">inputs</span> <span class="o">+</span> <span class="p">(</span><span class="s1">''</span><span class="p">,))),</span>
695 <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">_to_str</span><span class="p">,</span> <span class="p">(</span><span class="s1">''</span><span class="p">,)</span> <span class="o">+</span> <span class="n">outputs</span><span class="p">))</span>
696 <span class="p">)</span>
699 <span class="k">def</span> <span class="nf">_to_str</span><span class="p">(</span><span class="n">term</span><span class="p">):</span>
700 <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
701 <span class="k">try</span><span class="p">:</span>
702 <span class="n">t</span> <span class="o">=</span> <span class="n">term</span><span class="o">.</span><span class="n">prefix</span> <span class="o">==</span> <span class="s1">'s'</span>
703 <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
704 <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
705 <span class="k">return</span> <span class="s1">'[.</span><span class="si">%i</span><span class="s1">.]'</span> <span class="o">%</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span> <span class="k">if</span> <span class="n">t</span> <span class="k">else</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
707 <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
708 <span class="k">while</span> <span class="n">term</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
709 <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
710 <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_to_str</span><span class="p">(</span><span class="n">item</span><span class="p">))</span>
712 <span class="k">try</span><span class="p">:</span>
713 <span class="n">n</span> <span class="o">=</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
714 <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
715 <span class="n">n</span> <span class="o">=</span> <span class="n">term</span>
716 <span class="k">else</span><span class="p">:</span>
717 <span class="k">if</span> <span class="n">term</span><span class="o">.</span><span class="n">prefix</span> <span class="o">!=</span> <span class="s1">'s'</span><span class="p">:</span>
718 <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'Stack label: </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">term</span><span class="p">,))</span>
720 <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'.</span><span class="si">%s</span><span class="s1">.'</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,))</span>
721 <span class="k">return</span> <span class="s1">'[</span><span class="si">%s</span><span class="s1">]'</span> <span class="o">%</span> <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
725 <div class="section" id="compile">
726 <h3><code class="docutils literal notranslate"><span class="pre">compile_()</span></code><a class="headerlink" href="#compile" title="Permalink to this headline">¶</a></h3>
727 <p>Now we can write a compiler function to emit Python source code. (The
728 underscore suffix distiguishes it from the built-in <code class="docutils literal notranslate"><span class="pre">compile()</span></code>
730 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
731 <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
732 <span class="n">doc</span> <span class="o">=</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>
733 <span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">identifiers</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
734 <span class="n">i</span> <span class="o">=</span> <span class="n">o</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'stack'</span><span class="p">)</span>
735 <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">inputs</span><span class="p">:</span>
736 <span class="n">i</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">i</span>
737 <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">outputs</span><span class="p">:</span>
738 <span class="n">o</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">o</span>
739 <span class="k">return</span> <span class="s1">'''def </span><span class="si">%s</span><span class="s1">(stack):</span>
740 <span class="s1"> """</span><span class="si">%s</span><span class="s1">"""</span>
741 <span class="s1"> </span><span class="si">%s</span><span class="s1"> = stack</span>
742 <span class="s1"> return </span><span class="si">%s</span><span class="s1">'''</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
745 <p>Here it is in action:</p>
746 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">source</span> <span class="o">=</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
748 <span class="nb">print</span> <span class="n">source</span>
751 <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>
752 <span class="sd">"""([3 4 .5.] 1 2 0 -- [2 1 .5.])"""</span>
753 <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">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a2</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
754 <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">a2</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
758 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
759 <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</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>
760 <span class="k">return</span> <span class="p">((</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
764 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="p">{}</span>
766 <span class="nb">eval</span><span class="p">(</span><span class="nb">compile</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="s1">'__main__'</span><span class="p">,</span> <span class="s1">'single'</span><span class="p">),</span> <span class="p">{},</span> <span class="n">L</span><span class="p">)</span>
768 <span class="n">L</span><span class="p">[</span><span class="s1">'F'</span><span class="p">]</span>
771 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o"><</span><span class="n">function</span> <span class="n">F</span><span class="o">></span>
774 <p>Let’s try it out:</p>
775 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
776 <span class="kn">from</span> <span class="nn">joy.library</span> <span class="k">import</span> <span class="n">SimpleFunctionWrapper</span>
779 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'F'</span><span class="p">]</span> <span class="o">=</span> <span class="n">SimpleFunctionWrapper</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="s1">'F'</span><span class="p">])</span>
782 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 5 ...] 2 3 1 F'</span><span class="p">)</span>
785 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">]</span>
788 <p>With this, we have a partial Joy compiler that works on the subset of
789 Joy functions that manipulate stacks (both what I call “stack chatter”
790 and the ones that manipulate stacks on the stack.)</p>
791 <p>I’m probably going to modify the definition wrapper code to detect
792 definitions that can be compiled by this partial compiler and do it
793 automatically. It might be a reasonable idea to detect sequences of
794 compilable functions in definitions that have uncompilable functions in
795 them and just compile those. However, if your library is well-factored
796 this might be less helpful.</p>
798 <div class="section" id="compiling-library-functions">
799 <h3>Compiling Library Functions<a class="headerlink" href="#compiling-library-functions" title="Permalink to this headline">¶</a></h3>
800 <p>We can use <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> to generate many primitives in the library
801 from their stack effect comments:</p>
802 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
804 <span class="n">rolldown</span> <span class="o">=</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="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
806 <span class="n">rollup</span> <span class="o">=</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="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
808 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()</span>
810 <span class="n">swap</span> <span class="o">=</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="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
812 <span class="n">rest</span> <span class="o">=</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="p">(</span><span class="mi">2</span><span class="p">,)</span>
814 <span class="n">rrest</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
816 <span class="n">cons</span> <span class="o">=</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="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),)</span>
818 <span class="n">uncons</span> <span class="o">=</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="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
820 <span class="n">swons</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">cons</span><span class="p">)</span>
822 <span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
825 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
826 <span class="nb">print</span>
827 <span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span><span class="p">)</span>
828 <span class="nb">print</span>
831 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">cons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
832 <span class="sd">"""(1 2 -- [1 .2.])"""</span>
833 <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">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
834 <span class="k">return</span> <span class="p">((</span><span class="n">a0</span><span class="p">,</span> <span class="n">a1</span><span class="p">),</span> <span class="n">stack</span><span class="p">)</span>
837 <span class="k">def</span> <span class="nf">pop</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
838 <span class="sd">"""(1 --)"""</span>
839 <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
840 <span class="k">return</span> <span class="n">stack</span>
843 <span class="k">def</span> <span class="nf">rest</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
844 <span class="sd">"""([1 .2.] -- 2)"""</span>
845 <span class="p">((</span><span class="n">a0</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>
846 <span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
849 <span class="k">def</span> <span class="nf">rolldown</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
850 <span class="sd">"""(1 2 3 -- 2 3 1)"""</span>
851 <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">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
852 <span class="k">return</span> <span class="p">(</span><span class="n">a0</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">stack</span><span class="p">)))</span>
855 <span class="k">def</span> <span class="nf">rollup</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
856 <span class="sd">"""(1 2 3 -- 3 1 2)"""</span>
857 <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">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
858 <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="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
861 <span class="k">def</span> <span class="nf">rrest</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
862 <span class="sd">"""([0 1 .2.] -- 2)"""</span>
863 <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">a2</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
864 <span class="k">return</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
867 <span class="k">def</span> <span class="nf">swap</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
868 <span class="sd">"""(1 2 -- 2 1)"""</span>
869 <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">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
870 <span class="k">return</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">stack</span><span class="p">))</span>
873 <span class="k">def</span> <span class="nf">swons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
874 <span class="sd">"""(0 1 -- [1 .0.])"""</span>
875 <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">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
876 <span class="k">return</span> <span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="n">a0</span><span class="p">),</span> <span class="n">stack</span><span class="p">)</span>
879 <span class="k">def</span> <span class="nf">uncons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
880 <span class="sd">"""([1 .2.] -- 1 2)"""</span>
881 <span class="p">((</span><span class="n">a0</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>
882 <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">stack</span><span class="p">))</span>
887 <div class="section" id="part-iv-types-and-subtypes-of-arguments">
888 <h2>Part IV: Types and Subtypes of Arguments<a class="headerlink" href="#part-iv-types-and-subtypes-of-arguments" title="Permalink to this headline">¶</a></h2>
889 <p>So far we have dealt with types of functions, those dealing with simple
890 stack manipulation. Let’s extend our machinery to deal with types of
892 <div class="section" id="number-type">
893 <h3>“Number” Type<a class="headerlink" href="#number-type" title="Permalink to this headline">¶</a></h3>
894 <p>Consider the definition of <code class="docutils literal notranslate"><span class="pre">sqr</span></code>:</p>
895 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sqr</span> <span class="o">==</span> <span class="n">dup</span> <span class="n">mul</span>
898 <p>The <code class="docutils literal notranslate"><span class="pre">dup</span></code> function accepts one <em>anything</em> and returns two of that:</p>
899 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span> <span class="p">(</span><span class="mi">1</span> <span class="o">--</span> <span class="mi">1</span> <span class="mi">1</span><span class="p">)</span>
902 <p>And <code class="docutils literal notranslate"><span class="pre">mul</span></code> accepts two “numbers” (we’re ignoring ints vs. floats
903 vs. complex, etc., for now) and returns just one:</p>
904 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span> <span class="p">(</span><span class="n">n</span> <span class="n">n</span> <span class="o">--</span> <span class="n">n</span><span class="p">)</span>
907 <p>So we’re composing:</p>
908 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(1 -- 1 1)∘(n n -- n)
911 <p>The rules say we unify 1 with <code class="docutils literal notranslate"><span class="pre">n</span></code>:</p>
912 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> (1 -- 1 1)∘(n n -- n)
913 --------------------------- w/ {1: n}
917 <p>This involves detecting that “Any type” arguments can accept “numbers”.
918 If we were composing these functions the other way round this is still
920 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> (n n -- n)∘(1 -- 1 1)
921 --------------------------- w/ {1: n}
925 <p>The important thing here is that the mapping is going the same way in
926 both cases, from the “any” integer to the number</p>
928 <div class="section" id="distinguishing-numbers">
929 <h3>Distinguishing Numbers<a class="headerlink" href="#distinguishing-numbers" title="Permalink to this headline">¶</a></h3>
930 <p>We should also mind that the number that <code class="docutils literal notranslate"><span class="pre">mul</span></code> produces is not
931 (necessarily) the same as either of its inputs, which are not
932 (necessarily) the same as each other:</p>
933 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>mul (n2 n1 -- n3)
936 (1 -- 1 1)∘(n2 n1 -- n3)
937 -------------------------------- w/ {1: n2}
938 (n2 -- n2 )∘(n2 -- n3)
941 (n2 n1 -- n3)∘(1 -- 1 1 )
942 -------------------------------- w/ {1: n3}
943 (n2 n1 -- )∘( -- n3 n3)
947 <div class="section" id="distinguishing-types">
948 <h3>Distinguishing Types<a class="headerlink" href="#distinguishing-types" title="Permalink to this headline">¶</a></h3>
949 <p>So we need separate domains of “any” numbers and “number” numbers, and
950 we need to be able to ask the order of these domains. Now the notes on
951 the right side of rule three make more sense, eh?</p>
952 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
953 -------------------------------
954 (a -- b )∘(c -- d) t[i] == t[k] == u[j]
957 (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
958 -------------------------------
959 (a -- b )∘(c -- d) t[i] == u[k] == u[j]
962 <p>The indices <code class="docutils literal notranslate"><span class="pre">i</span></code>, <code class="docutils literal notranslate"><span class="pre">k</span></code>, and <code class="docutils literal notranslate"><span class="pre">j</span></code> are the number part of our labels
963 and <code class="docutils literal notranslate"><span class="pre">t</span></code> and <code class="docutils literal notranslate"><span class="pre">u</span></code> are the domains.</p>
964 <p>By creative use of Python’s “double underscore” methods we can define a
965 Python class hierarchy of Joy types and use the <code class="docutils literal notranslate"><span class="pre">issubclass()</span></code> method
966 to establish domain ordering, as well as other handy behaviour that will
967 make it fairly easy to reuse most of the code above.</p>
968 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">AnyJoyType</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
970 <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'a'</span>
972 <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">number</span><span class="p">):</span>
973 <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
975 <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
976 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span><span class="p">)</span>
978 <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
979 <span class="k">return</span> <span class="p">(</span>
980 <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="vm">__class__</span><span class="p">)</span>
981 <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">prefix</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span>
982 <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">number</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span>
983 <span class="p">)</span>
985 <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>
986 <span class="k">return</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>
988 <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
989 <span class="k">return</span> <span class="bp">self</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="n">number</span> <span class="o">+</span> <span class="n">other</span><span class="p">)</span>
990 <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
992 <span class="k">def</span> <span class="nf">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
993 <span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
996 <span class="k">class</span> <span class="nc">NumberJoyType</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">'n'</span>
997 <span class="k">class</span> <span class="nc">FloatJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'f'</span>
998 <span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">FloatJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'i'</span>
1001 <span class="k">class</span> <span class="nc">StackJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
1002 <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'s'</span>
1005 <span class="n">_R</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
1006 <span class="n">A</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1007 <span class="n">N</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1008 <span class="n">S</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">StackJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1011 <p>Mess with it a little:</p>
1012 <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">permutations</span>
1015 <p>“Any” types can be specialized to numbers and stacks, but not vice
1017 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</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> <span class="mi">2</span><span class="p">):</span>
1018 <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">'>='</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">a</span> <span class="o">>=</span> <span class="n">b</span>
1021 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a0</span> <span class="o">>=</span> <span class="n">n0</span> <span class="o">-></span> <span class="kc">True</span>
1022 <span class="n">a0</span> <span class="o">>=</span> <span class="n">s0</span> <span class="o">-></span> <span class="kc">True</span>
1023 <span class="n">n0</span> <span class="o">>=</span> <span class="n">a0</span> <span class="o">-></span> <span class="kc">False</span>
1024 <span class="n">n0</span> <span class="o">>=</span> <span class="n">s0</span> <span class="o">-></span> <span class="kc">False</span>
1025 <span class="n">s0</span> <span class="o">>=</span> <span class="n">a0</span> <span class="o">-></span> <span class="kc">False</span>
1026 <span class="n">s0</span> <span class="o">>=</span> <span class="n">n0</span> <span class="o">-></span> <span class="kc">False</span>
1029 <p>Our crude <a class="reference external" href="https://en.wikipedia.org/wiki/Numerical_tower">Numerical
1030 Tower</a> of <em>numbers</em> >
1031 <em>floats</em> > <em>integers</em> works as well (but we’re not going to use it yet):</p>
1032 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</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">FloatJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">IntJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">)),</span> <span class="mi">2</span><span class="p">):</span>
1033 <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">'>='</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">a</span> <span class="o">>=</span> <span class="n">b</span>
1036 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a0</span> <span class="o">>=</span> <span class="n">n0</span> <span class="o">-></span> <span class="kc">True</span>
1037 <span class="n">a0</span> <span class="o">>=</span> <span class="n">f0</span> <span class="o">-></span> <span class="kc">True</span>
1038 <span class="n">a0</span> <span class="o">>=</span> <span class="n">i0</span> <span class="o">-></span> <span class="kc">True</span>
1039 <span class="n">n0</span> <span class="o">>=</span> <span class="n">a0</span> <span class="o">-></span> <span class="kc">False</span>
1040 <span class="n">n0</span> <span class="o">>=</span> <span class="n">f0</span> <span class="o">-></span> <span class="kc">True</span>
1041 <span class="n">n0</span> <span class="o">>=</span> <span class="n">i0</span> <span class="o">-></span> <span class="kc">True</span>
1042 <span class="n">f0</span> <span class="o">>=</span> <span class="n">a0</span> <span class="o">-></span> <span class="kc">False</span>
1043 <span class="n">f0</span> <span class="o">>=</span> <span class="n">n0</span> <span class="o">-></span> <span class="kc">False</span>
1044 <span class="n">f0</span> <span class="o">>=</span> <span class="n">i0</span> <span class="o">-></span> <span class="kc">True</span>
1045 <span class="n">i0</span> <span class="o">>=</span> <span class="n">a0</span> <span class="o">-></span> <span class="kc">False</span>
1046 <span class="n">i0</span> <span class="o">>=</span> <span class="n">n0</span> <span class="o">-></span> <span class="kc">False</span>
1047 <span class="n">i0</span> <span class="o">>=</span> <span class="n">f0</span> <span class="o">-></span> <span class="kc">False</span>
1051 <div class="section" id="typing-sqr">
1052 <h3>Typing <code class="docutils literal notranslate"><span class="pre">sqr</span></code><a class="headerlink" href="#typing-sqr" title="Permalink to this headline">¶</a></h3>
1053 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</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">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1055 <span class="n">mul</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="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],)</span>
1058 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span>
1061 <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>
1064 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span>
1067 <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="n">n2</span><span class="p">),</span> <span class="p">(</span><span class="n">n3</span><span class="p">,))</span>
1071 <div class="section" id="modifying-the-inferencer">
1072 <h3>Modifying the Inferencer<a class="headerlink" href="#modifying-the-inferencer" title="Permalink to this headline">¶</a></h3>
1073 <p>Re-labeling still works fine:</p>
1074 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
1076 <span class="n">foo</span>
1079 <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">n1001</span><span class="p">,</span> <span class="n">n1002</span><span class="p">),</span> <span class="p">(</span><span class="n">n1003</span><span class="p">,)))</span>
1082 <div class="section" id="delabel-version-2">
1083 <h4><code class="docutils literal notranslate"><span class="pre">delabel()</span></code> version 2<a class="headerlink" href="#delabel-version-2" title="Permalink to this headline">¶</a></h4>
1084 <p>The <code class="docutils literal notranslate"><span class="pre">delabel()</span></code> function needs an overhaul. It now has to keep track
1085 of how many labels of each domain it has “seen”.</p>
1086 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">Counter</span>
1089 <span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">seen</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
1090 <span class="k">if</span> <span class="n">seen</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1091 <span class="k">assert</span> <span class="n">c</span> <span class="ow">is</span> <span class="kc">None</span>
1092 <span class="n">seen</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="p">{},</span> <span class="n">Counter</span><span class="p">()</span>
1094 <span class="k">try</span><span class="p">:</span>
1095 <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
1096 <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
1097 <span class="k">pass</span>
1099 <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>
1100 <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>
1101 <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>
1102 <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
1104 <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">delabel</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">seen</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">f</span><span class="p">)</span>
1107 <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>
1110 <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>
1114 <div class="section" id="unify-version-3">
1115 <h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 3<a class="headerlink" href="#unify-version-3" title="Permalink to this headline">¶</a></h4>
1116 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</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="kc">None</span><span class="p">):</span>
1117 <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1118 <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
1119 <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
1120 <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>
1121 <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>
1123 <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
1124 <span class="k">return</span> <span class="n">s</span>
1126 <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="n">AnyJoyType</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="n">AnyJoyType</span><span class="p">):</span>
1127 <span class="k">if</span> <span class="n">u</span> <span class="o">>=</span> <span class="n">v</span><span class="p">:</span>
1128 <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>
1129 <span class="k">return</span> <span class="n">s</span>
1130 <span class="k">if</span> <span class="n">v</span> <span class="o">>=</span> <span class="n">u</span><span class="p">:</span>
1131 <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>
1132 <span class="k">return</span> <span class="n">s</span>
1133 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.'</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
1135 <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>
1136 <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>
1137 <span class="k">raise</span> <span class="ne">TypeError</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>
1138 <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>
1139 <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>
1140 <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>
1141 <span class="k">break</span>
1142 <span class="k">return</span> <span class="n">s</span>
1144 <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">tuple</span><span class="p">):</span>
1145 <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">u</span><span class="p">):</span>
1146 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.'</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
1147 <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>
1148 <span class="k">return</span> <span class="n">s</span>
1150 <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>
1151 <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">v</span><span class="p">):</span>
1152 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.'</span> <span class="o">%</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">u</span><span class="p">))</span>
1153 <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>
1154 <span class="k">return</span> <span class="n">s</span>
1156 <span class="k">return</span> <span class="kc">False</span>
1159 <span class="k">def</span> <span class="nf">stacky</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
1160 <span class="k">return</span> <span class="n">thing</span><span class="o">.</span><span class="vm">__class__</span> <span class="ow">in</span> <span class="p">{</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">}</span>
1163 <p>Rewrite the stack effect comments:</p>
1164 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
1166 <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</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="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</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">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1168 <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</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="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
1170 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">()</span>
1172 <span class="n">popop</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">()</span>
1174 <span class="n">popd</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</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">1</span><span class="p">],)</span>
1176 <span class="n">popdd</span> <span class="o">=</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">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</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">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
1178 <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1180 <span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="n">A</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="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
1182 <span class="n">rrest</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
1184 <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</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="p">((</span><span class="n">A</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>
1186 <span class="n">ccons</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">cons</span><span class="p">)</span>
1188 <span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="n">A</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="p">(</span><span class="n">A</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>
1190 <span class="n">swons</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">cons</span><span class="p">)</span>
1192 <span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</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">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1194 <span class="n">dupd</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</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">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1196 <span class="n">mul</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="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],)</span>
1198 <span class="n">sqrt</span> <span class="o">=</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>
1200 <span class="n">first</span> <span class="o">=</span> <span class="p">((</span><span class="n">A</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="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
1202 <span class="n">second</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">first</span><span class="p">)</span>
1204 <span class="n">third</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">second</span><span class="p">)</span>
1206 <span class="n">tuck</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</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">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1208 <span class="n">over</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</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">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
1210 <span class="n">succ</span> <span class="o">=</span> <span class="n">pred</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">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],)</span>
1212 <span class="n">divmod_</span> <span class="o">=</span> <span class="n">pm</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</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">N</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span>
1214 <span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
1217 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DEFS</span> <span class="o">=</span> <span class="n">defs</span><span class="p">()</span>
1220 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
1221 <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'='</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>
1224 <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>
1225 <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>
1226 <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>
1227 <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>
1228 <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>
1229 <span class="n">first</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>
1230 <span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="n">n2</span> <span class="o">--</span> <span class="n">n3</span><span class="p">)</span>
1231 <span class="n">over</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">a1</span> <span class="n">a2</span><span class="p">)</span>
1232 <span class="n">pm</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>
1233 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
1234 <span class="n">popd</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="p">)</span>
1235 <span class="n">popdd</span> <span class="o">=</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="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1236 <span class="n">popop</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="p">)</span>
1237 <span class="n">pred</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>
1238 <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>
1239 <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>
1240 <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>
1241 <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>
1242 <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>
1243 <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>
1244 <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>
1245 <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>
1246 <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>
1247 <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>
1248 <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>
1249 <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>
1252 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">DEFS</span><span class="p">)</span>
1256 <div class="section" id="compose-dup-and-mul">
1257 <h4>Compose <code class="docutils literal notranslate"><span class="pre">dup</span></code> and <code class="docutils literal notranslate"><span class="pre">mul</span></code><a class="headerlink" href="#compose-dup-and-mul" title="Permalink to this headline">¶</a></h4>
1258 <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>
1261 <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>
1264 <p>Revisit the <code class="docutils literal notranslate"><span class="pre">F</span></code> function, works fine.</p>
1265 <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>
1266 <span class="n">F</span>
1269 <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>
1272 <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>
1275 <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>
1278 <p>Some otherwise inefficient functions are no longer to be feared. We can
1279 also get the effect of combinators in some limited cases.</p>
1280 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">neato</span><span class="p">(</span><span class="o">*</span><span class="n">funcs</span><span class="p">):</span>
1281 <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="n">funcs</span><span class="p">))</span>
1284 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [swap] dip</span>
1285 <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>
1288 <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>
1291 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [popop] dipd</span>
1292 <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>
1295 <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>
1298 <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>
1299 <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>
1302 <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>
1306 <div class="section" id="compile-version-2">
1307 <h4><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 2<a class="headerlink" href="#compile-version-2" title="Permalink to this headline">¶</a></h4>
1308 <p>Because the type labels represent themselves as valid Python identifiers
1309 the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function doesn’t need to generate them anymore:</p>
1310 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
1311 <span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">f</span>
1312 <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1313 <span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">)</span>
1314 <span class="n">i</span> <span class="o">=</span> <span class="n">o</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'stack'</span><span class="p">)</span>
1315 <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">inputs</span><span class="p">:</span>
1316 <span class="n">i</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">i</span>
1317 <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">outputs</span><span class="p">:</span>
1318 <span class="n">o</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">o</span>
1319 <span class="k">return</span> <span class="s1">'''def </span><span class="si">%s</span><span class="s1">(stack):</span>
1320 <span class="s1"> """</span><span class="si">%s</span><span class="s1">"""</span>
1321 <span class="s1"> </span><span class="si">%s</span><span class="s1"> = stack</span>
1322 <span class="s1"> return </span><span class="si">%s</span><span class="s1">'''</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
1325 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
1328 <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>
1329 <span class="sd">"""([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])"""</span>
1330 <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>
1331 <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>
1334 <p>But it cannot magically create new functions that involve e.g. math and
1335 such. Note that this is <em>not</em> a <code class="docutils literal notranslate"><span class="pre">sqr</span></code> function implementation:</p>
1336 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'sqr'</span><span class="p">,</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>
1339 <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>
1340 <span class="sd">"""(n1 -- n2)"""</span>
1341 <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>
1342 <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>
1345 <p>(Eventually I should come back around to this becuase it’s not tooo
1346 difficult to exend this code to be able to compile e.g.
1347 <code class="docutils literal notranslate"><span class="pre">n2</span> <span class="pre">=</span> <span class="pre">mul(n1,</span> <span class="pre">n1)</span></code> for <code class="docutils literal notranslate"><span class="pre">mul</span></code> with the right variable names and
1348 insert it in the right place. It requires a little more support from the
1349 library functions, in that we need to know to call <code class="docutils literal notranslate"><span class="pre">mul()</span></code> the Python
1350 function for <code class="docutils literal notranslate"><span class="pre">mul</span></code> the Joy function, but since <em>most</em> of the math
1351 functions (at least) are already wrappers it should be straightforward.)</p>
1353 <div class="section" id="compilable">
1354 <h4><code class="docutils literal notranslate"><span class="pre">compilable()</span></code><a class="headerlink" href="#compilable" title="Permalink to this headline">¶</a></h4>
1355 <p>The functions that <em>can</em> be compiled are the ones that have only
1356 <code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> and <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> labels in their stack effect
1357 comments. We can write a function to check that:</p>
1358 <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">imap</span>
1361 <span class="k">def</span> <span class="nf">compilable</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
1362 <span class="k">return</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="ow">and</span> <span class="nb">all</span><span class="p">(</span><span class="n">imap</span><span class="p">(</span><span class="n">compilable</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span> <span class="ow">or</span> <span class="n">stacky</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
1365 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
1366 <span class="k">if</span> <span class="n">compilable</span><span class="p">(</span><span class="n">stack_effect_comment</span><span class="p">):</span>
1367 <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'='</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>
1370 <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>
1371 <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>
1372 <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>
1373 <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>
1374 <span class="n">first</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>
1375 <span class="n">over</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">a1</span> <span class="n">a2</span><span class="p">)</span>
1376 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
1377 <span class="n">popd</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="p">)</span>
1378 <span class="n">popdd</span> <span class="o">=</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="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1379 <span class="n">popop</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="p">)</span>
1380 <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>
1381 <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>
1382 <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>
1383 <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>
1384 <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>
1385 <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>
1386 <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>
1387 <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>
1388 <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>
1389 <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>
1395 <div class="section" id="part-v-functions-that-use-the-stack">
1396 <h2>Part V: Functions that use the Stack<a class="headerlink" href="#part-v-functions-that-use-the-stack" title="Permalink to this headline">¶</a></h2>
1397 <p>Consider the <code class="docutils literal notranslate"><span class="pre">stack</span></code> function which grabs the whole stack, quotes it,
1398 and puts it on itself:</p>
1399 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stack</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>
1400 <span class="n">stack</span> <span class="p">(</span><span class="o">...</span> <span class="n">a</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a</span> <span class="p">[</span><span class="n">a</span> <span class="o">...</span><span class="p">]</span> <span class="p">)</span>
1401 <span class="n">stack</span> <span class="p">(</span><span class="o">...</span> <span class="n">b</span> <span class="n">a</span> <span class="o">--</span> <span class="o">...</span> <span class="n">b</span> <span class="n">a</span> <span class="p">[</span><span class="n">a</span> <span class="n">b</span> <span class="o">...</span><span class="p">])</span>
1404 <p>We would like to represent this in Python somehow. To do this we use a
1405 simple, elegant trick.</p>
1406 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stack</span> <span class="n">S</span> <span class="o">--</span> <span class="p">(</span> <span class="n">S</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span>
1407 <span class="n">stack</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span> <span class="o">--</span> <span class="p">(</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">S</span><span class="p">),</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">S</span><span class="p">))</span>
1408 <span class="n">stack</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S</span><span class="p">))</span> <span class="o">--</span> <span class="p">(</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S</span><span class="p">)),</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S</span><span class="p">)))</span>
1411 <p>Instead of representing the stack effect comments as a single tuple
1412 (with N items in it) we use the same cons-list structure to hold the
1413 sequence and <code class="docutils literal notranslate"><span class="pre">unify()</span></code> the whole comments.</p>
1414 <div class="section" id="stackuncons">
1415 <h3><code class="docutils literal notranslate"><span class="pre">stack∘uncons</span></code><a class="headerlink" href="#stackuncons" title="Permalink to this headline">¶</a></h3>
1416 <p>Let’s try composing <code class="docutils literal notranslate"><span class="pre">stack</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code>. We want this result:</p>
1417 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>stack∘uncons (... a -- ... a a [...])
1420 <p>The stack effects are:</p>
1421 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stack</span> <span class="o">=</span> <span class="n">S</span> <span class="o">--</span> <span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span>
1423 <span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="n">Z</span><span class="p">),</span> <span class="n">S</span><span class="p">)</span> <span class="o">--</span> <span class="p">(</span><span class="n">Z</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">S</span><span class="p">))</span>
1427 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> S -- (S, S) ∘ ((a, Z), S) -- (Z, (a, S ))
1429 (a, Z) -- ∘ -- (Z, (a, (a, Z)))
1433 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>stack∘uncons == (a, Z) -- (Z, (a, (a, Z)))
1438 <div class="section" id="stackunconsuncons">
1439 <h3><code class="docutils literal notranslate"><span class="pre">stack∘uncons∘uncons</span></code><a class="headerlink" href="#stackunconsuncons" title="Permalink to this headline">¶</a></h3>
1440 <p>Let’s try <code class="docutils literal notranslate"><span class="pre">stack∘uncons∘uncons</span></code>:</p>
1441 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(a, S ) -- (S, (a, (a, S ))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
1445 (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
1447 w/ { S`: (a, (a, (b, Z))) }
1449 (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), (a, (a, (b, Z)))) -- (Z, (b, (a, (a, (b, Z)))))
1451 (a, (b, Z)) -- (Z, (b, (a, (a, (b, Z)))))
1455 <div class="section" id="compose-version-2">
1456 <h4><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 2<a class="headerlink" href="#compose-version-2" title="Permalink to this headline">¶</a></h4>
1457 <p>This function has to be modified to use the new datastructures and it is
1458 no longer recursive, instead recursion happens as part of unification.
1459 Further, the first and second of Pöial’s rules are now handled
1460 automatically by the unification algorithm. (One easy way to see this is
1461 that now an empty stack effect comment is represented by a
1462 <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> instance which is not “falsey” and so neither of the
1463 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
1464 the “truthiness” of <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> to false to let e.g.
1465 <code class="docutils literal notranslate"><span class="pre">joy.utils.stack.concat</span></code> work with our stack effect comment cons-list
1467 <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>
1468 <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>
1469 <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>
1470 <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"># s can also be the empty dict, which is ok.</span>
1471 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.'</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>
1472 <span class="k">return</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">))</span>
1475 <p>I don’t want to rewrite all the defs myself, so I’ll write a little
1476 conversion function instead. This is programmer’s laziness.</p>
1477 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sequence_to_stack</span><span class="p">(</span><span class="n">seq</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="n">StackJoyType</span><span class="p">(</span><span class="mi">23</span><span class="p">)):</span>
1478 <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">seq</span><span class="p">:</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">stack</span>
1479 <span class="k">return</span> <span class="n">stack</span>
1481 <span class="n">NEW_DEFS</span> <span class="o">=</span> <span class="p">{</span>
1482 <span class="n">name</span><span class="p">:</span> <span class="p">(</span><span class="n">sequence_to_stack</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="n">sequence_to_stack</span><span class="p">(</span><span class="n">o</span><span class="p">))</span>
1483 <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span> <span class="ow">in</span> <span class="n">DEFS</span><span class="o">.</span><span class="n">iteritems</span><span class="p">()</span>
1484 <span class="p">}</span>
1485 <span class="n">NEW_DEFS</span><span class="p">[</span><span class="s1">'stack'</span><span class="p">]</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">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">0</span><span class="p">])</span>
1486 <span class="n">NEW_DEFS</span><span class="p">[</span><span class="s1">'swaack'</span><span class="p">]</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="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>
1487 <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="p">)</span>
1490 <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>
1493 <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>
1496 <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>
1499 <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>
1502 <p>The display function should be changed too.</p>
1505 <div class="section" id="doc-from-stack-effect-version-2">
1506 <h3><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code> version 2<a class="headerlink" href="#doc-from-stack-effect-version-2" title="Permalink to this headline">¶</a></h3>
1507 <p>Clunky junk, but it will suffice for now.</p>
1508 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
1509 <span class="n">switch</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="c1"># Do we need to display the '...' for the rest of the main stack?</span>
1510 <span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">_f</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">),</span> <span class="n">_f</span><span class="p">(</span><span class="n">outputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">)</span>
1511 <span class="k">if</span> <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
1512 <span class="n">i</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'...'</span><span class="p">)</span>
1513 <span class="n">o</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">'...'</span><span class="p">)</span>
1514 <span class="k">return</span> <span class="s1">'(</span><span class="si">%s</span><span class="s1">--</span><span class="si">%s</span><span class="s1">)'</span> <span class="o">%</span> <span class="p">(</span>
1515 <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">reversed</span><span class="p">([</span><span class="s1">''</span><span class="p">]</span> <span class="o">+</span> <span class="n">i</span><span class="p">)),</span>
1516 <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">reversed</span><span class="p">(</span><span class="n">o</span> <span class="o">+</span> <span class="p">[</span><span class="s1">''</span><span class="p">])),</span>
1517 <span class="p">)</span>
1520 <span class="k">def</span> <span class="nf">_f</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">switch</span><span class="p">):</span>
1521 <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
1522 <span class="k">while</span> <span class="n">term</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1523 <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
1524 <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
1525 <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
1526 <span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="n">_to_str</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">term</span><span class="p">,</span> <span class="n">switch</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">a</span><span class="p">]</span>
1527 <span class="k">return</span> <span class="n">a</span>
1530 <span class="k">def</span> <span class="nf">_to_str</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">switch</span><span class="p">):</span>
1531 <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1532 <span class="k">if</span> <span class="n">term</span> <span class="o">==</span> <span class="n">stack</span><span class="p">:</span>
1533 <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
1534 <span class="k">return</span> <span class="s1">'[...]'</span>
1535 <span class="k">return</span> <span class="p">(</span>
1536 <span class="s1">'[.</span><span class="si">%i</span><span class="s1">.]'</span> <span class="o">%</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
1537 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">)</span>
1538 <span class="k">else</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
1539 <span class="p">)</span>
1541 <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
1542 <span class="k">while</span> <span class="n">term</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1543 <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
1544 <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_to_str</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">switch</span><span class="p">))</span>
1545 <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
1546 <span class="k">if</span> <span class="n">term</span> <span class="o">==</span> <span class="n">stack</span><span class="p">:</span>
1547 <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
1548 <span class="n">end</span> <span class="o">=</span> <span class="s1">'...'</span>
1549 <span class="k">else</span><span class="p">:</span>
1550 <span class="n">end</span> <span class="o">=</span> <span class="s1">'.</span><span class="si">%i</span><span class="s1">.'</span> <span class="o">%</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
1551 <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">end</span><span class="p">)</span>
1552 <span class="k">return</span> <span class="s1">'[</span><span class="si">%s</span><span class="s1">]'</span> <span class="o">%</span> <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
1555 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
1556 <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'='</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>
1559 <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>
1560 <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>
1561 <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>
1562 <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>
1563 <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>
1564 <span class="n">first</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>
1565 <span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="n">n2</span> <span class="o">--</span> <span class="n">n3</span><span class="p">)</span>
1566 <span class="n">over</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">a1</span> <span class="n">a2</span><span class="p">)</span>
1567 <span class="n">pm</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>
1568 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
1569 <span class="n">popd</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="p">)</span>
1570 <span class="n">popdd</span> <span class="o">=</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="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1571 <span class="n">popop</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="p">)</span>
1572 <span class="n">pred</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>
1573 <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>
1574 <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>
1575 <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>
1576 <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>
1577 <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>
1578 <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>
1579 <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>
1580 <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>
1581 <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>
1582 <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>
1583 <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>
1584 <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>
1585 <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>
1586 <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>
1589 <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>
1590 <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>
1591 <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>
1592 <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>
1595 <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>
1597 <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>
1599 <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>
1601 <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>
1604 <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>
1607 <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>
1610 <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>
1612 <span class="n">Q</span>
1615 <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>
1618 <div class="section" id="compile-version-3">
1619 <h4><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 3<a class="headerlink" href="#compile-version-3" title="Permalink to this headline">¶</a></h4>
1620 <p>This makes the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function pretty simple as the stack effect
1621 comments are now already in the form needed for the Python code:</p>
1622 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
1623 <span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">f</span>
1624 <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1625 <span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
1626 <span class="k">return</span> <span class="s1">'''def </span><span class="si">%s</span><span class="s1">(stack):</span>
1627 <span class="s1"> """</span><span class="si">%s</span><span class="s1">"""</span>
1628 <span class="s1"> </span><span class="si">%s</span><span class="s1"> = stack</span>
1629 <span class="s1"> return </span><span class="si">%s</span><span class="s1">'''</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
1632 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'Q'</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span>
1635 <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>
1636 <span class="sd">"""(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])"""</span>
1637 <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>
1638 <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>
1641 <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>
1642 <span class="n">enstacken</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">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>
1645 <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">unstack</span><span class="p">)</span>
1648 <div class="highlight-default notranslate"><div class="highlight"><pre><span></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>
1651 <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">enstacken</span><span class="p">)</span>
1654 <div class="highlight-default notranslate"><div class="highlight"><pre><span></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>
1657 <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>
1660 <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>
1663 <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>
1666 <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>
1669 <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>
1672 <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>
1678 <div class="section" id="part-vi-multiple-stack-effects">
1679 <h2>Part VI: Multiple Stack Effects<a class="headerlink" href="#part-vi-multiple-stack-effects" title="Permalink to this headline">¶</a></h2>
1681 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'i'</span>
1684 <span class="n">F</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">FloatJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1685 <span class="n">I</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">IntJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1688 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">muls</span> <span class="o">=</span> <span class="p">[</span>
1689 <span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</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">I</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">0</span><span class="p">])),</span>
1690 <span class="p">((</span><span class="n">F</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</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">F</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">0</span><span class="p">])),</span>
1691 <span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</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><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</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">0</span><span class="p">])),</span>
1692 <span class="p">((</span><span class="n">F</span><span class="p">[</span><span class="mi">2</span><span class="p">],</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><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</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">0</span><span class="p">])),</span>
1693 <span class="p">]</span>
1696 <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">muls</span><span class="p">:</span>
1697 <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>
1700 <div class="highlight-default notranslate"><div class="highlight"><pre><span></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>
1701 <span class="p">(</span><span class="n">i1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span>
1702 <span class="p">(</span><span class="n">f1</span> <span class="n">i2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span>
1703 <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>
1706 <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">muls</span><span class="p">:</span>
1707 <span class="k">try</span><span class="p">:</span>
1708 <span class="n">e</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
1709 <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
1710 <span class="k">continue</span>
1711 <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>
1714 <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>
1715 <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>
1718 <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>
1721 <span class="k">def</span> <span class="nf">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>
1722 <span class="k">for</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">product</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
1723 <span class="k">try</span><span class="p">:</span>
1724 <span class="k">yield</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>
1725 <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
1726 <span class="k">pass</span>
1729 <span class="k">def</span> <span class="nf">MC</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
1730 <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>
1733 <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>
1734 <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>
1737 <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>
1740 <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>
1741 <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>
1744 <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>
1745 <span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
1748 <div class="section" id="representing-an-unbounded-sequence-of-types">
1749 <h3>Representing an Unbounded Sequence of Types<a class="headerlink" href="#representing-an-unbounded-sequence-of-types" title="Permalink to this headline">¶</a></h3>
1750 <p>We can borrow a trick from <a class="reference external" href="https://en.wikipedia.org/wiki/Brzozowski_derivative">Brzozowski’s Derivatives of Regular
1752 invent a new type of type variable, a “sequence type” (I think this is
1753 what they mean in the literature by that term…) or “<a class="reference external" href="https://en.wikipedia.org/wiki/Kleene_star">Kleene
1754 Star</a>” type. I’m going to
1755 represent it as a type letter and the asterix, so a sequence of zero or
1756 more <code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> variables would be:</p>
1757 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span><span class="o">*</span>
1760 <p>The <code class="docutils literal notranslate"><span class="pre">A*</span></code> works by splitting the universe into two alternate histories:</p>
1761 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span><span class="o">*</span> <span class="o">-></span> <span class="mi">0</span> <span class="o">|</span> <span class="n">A</span> <span class="n">A</span><span class="o">*</span>
1764 <p>The Kleene star variable disappears in one universe, and in the other it
1765 turns into an <code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> variable followed by itself again. We have
1766 to return all universes (represented by their substitution dicts, the
1767 “unifiers”) that don’t lead to type conflicts.</p>
1768 <p>Consider unifying two stacks (the lowercase letters are any type
1769 variables of the kinds we have defined so far):</p>
1770 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">a</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span><span class="n">c</span> <span class="n">d</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1771 <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="n">c</span><span class="p">:</span> <span class="n">a</span><span class="p">}</span>
1772 <span class="p">[</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span> <span class="n">d</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1775 <p>Now we have to split universes to unify <code class="docutils literal notranslate"><span class="pre">A*</span></code>. In the first universe it
1777 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span><span class="n">d</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1778 <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="n">d</span><span class="p">:</span> <span class="n">b</span><span class="p">,</span> <span class="o">.</span><span class="mf">1.</span><span class="p">:</span> <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
1779 <span class="p">[]</span> <span class="n">U</span> <span class="p">[]</span>
1782 <p>While in the second it spawns an <code class="docutils literal notranslate"><span class="pre">A</span></code>, which we will label <code class="docutils literal notranslate"><span class="pre">e</span></code>:</p>
1783 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">e</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span><span class="n">d</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1784 <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="n">d</span><span class="p">:</span> <span class="n">e</span><span class="p">}</span>
1785 <span class="p">[</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1786 <span class="n">w</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">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
1787 <span class="p">[</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span>
1790 <p>Giving us two unifiers:</p>
1791 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">c</span><span class="p">:</span> <span class="n">a</span><span class="p">,</span> <span class="n">d</span><span class="p">:</span> <span class="n">b</span><span class="p">,</span> <span class="o">.</span><span class="mf">1.</span><span class="p">:</span> <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
1792 <span class="p">{</span><span class="n">c</span><span class="p">:</span> <span class="n">a</span><span class="p">,</span> <span class="n">d</span><span class="p">:</span> <span class="n">e</span><span class="p">,</span> <span class="o">.</span><span class="mf">1.</span><span class="p">:</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
1795 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">KleeneStar</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
1797 <span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
1799 <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">number</span><span class="p">):</span>
1800 <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
1801 <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
1802 <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
1804 <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1805 <span class="k">return</span> <span class="s1">'</span><span class="si">%s%i</span><span class="s1">*'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">kind</span><span class="o">.</span><span class="n">prefix</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span><span class="p">)</span>
1807 <span class="k">def</span> <span class="nf">another</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1808 <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
1809 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span><span class="p">(</span><span class="mi">10000</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">count</span><span class="p">)</span>
1811 <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
1812 <span class="k">return</span> <span class="p">(</span>
1813 <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="vm">__class__</span><span class="p">)</span>
1814 <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">number</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span>
1815 <span class="p">)</span>
1817 <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>
1818 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span> <span class="o">>=</span> <span class="n">other</span><span class="o">.</span><span class="n">kind</span>
1820 <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
1821 <span class="k">return</span> <span class="bp">self</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="n">number</span> <span class="o">+</span> <span class="n">other</span><span class="p">)</span>
1822 <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
1824 <span class="k">def</span> <span class="nf">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1825 <span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
1827 <span class="k">class</span> <span class="nc">AnyStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
1828 <span class="k">class</span> <span class="nc">NumberStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">NumberJoyType</span>
1829 <span class="c1">#class FloatStarJoyType(KleeneStar): kind = FloatJoyType</span>
1830 <span class="c1">#class IntStarJoyType(KleeneStar): kind = IntJoyType</span>
1831 <span class="k">class</span> <span class="nc">StackStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">StackJoyType</span>
1834 <span class="n">As</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">AnyStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1835 <span class="n">Ns</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">NumberStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1836 <span class="n">Ss</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">StackStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1839 <div class="section" id="unify-version-4">
1840 <h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 4<a class="headerlink" href="#unify-version-4" title="Permalink to this headline">¶</a></h4>
1841 <p>Can now return multiple results…</p>
1842 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</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="kc">None</span><span class="p">):</span>
1843 <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1844 <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
1845 <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
1846 <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>
1847 <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>
1849 <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
1850 <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1852 <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="n">AnyJoyType</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="n">AnyJoyType</span><span class="p">):</span>
1853 <span class="k">if</span> <span class="n">u</span> <span class="o">>=</span> <span class="n">v</span><span class="p">:</span>
1854 <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>
1855 <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1856 <span class="k">if</span> <span class="n">v</span> <span class="o">>=</span> <span class="n">u</span><span class="p">:</span>
1857 <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>
1858 <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1859 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.'</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
1861 <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>
1862 <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>
1863 <span class="k">raise</span> <span class="ne">TypeError</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>
1865 <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">v</span>
1866 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">KleeneStar</span><span class="p">):</span>
1867 <span class="c1"># Two universes, in one the Kleene star disappears and unification</span>
1868 <span class="c1"># continues without it...</span>
1869 <span class="n">s0</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
1871 <span class="c1"># In the other it spawns a new variable.</span>
1872 <span class="n">s1</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">another</span><span class="p">(),</span> <span class="n">v</span><span class="p">))</span>
1874 <span class="n">t</span> <span class="o">=</span> <span class="n">s0</span> <span class="o">+</span> <span class="n">s1</span>
1875 <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">t</span><span class="p">:</span>
1876 <span class="n">sn</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
1877 <span class="k">return</span> <span class="n">t</span>
1879 <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">u</span>
1880 <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">KleeneStar</span><span class="p">):</span>
1881 <span class="n">s0</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
1882 <span class="n">s1</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">another</span><span class="p">(),</span> <span class="n">u</span><span class="p">))</span>
1883 <span class="n">t</span> <span class="o">=</span> <span class="n">s0</span> <span class="o">+</span> <span class="n">s1</span>
1884 <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">t</span><span class="p">:</span>
1885 <span class="n">sn</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
1886 <span class="k">return</span> <span class="n">t</span>
1888 <span class="n">ses</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">s</span><span class="p">)</span>
1889 <span class="n">results</span> <span class="o">=</span> <span class="p">()</span>
1890 <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">ses</span><span class="p">:</span>
1891 <span class="n">results</span> <span class="o">+=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">sn</span><span class="p">)</span>
1892 <span class="k">return</span> <span class="n">results</span>
1894 <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">tuple</span><span class="p">):</span>
1895 <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">u</span><span class="p">):</span>
1896 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.'</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
1897 <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>
1898 <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1900 <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>
1901 <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">v</span><span class="p">):</span>
1902 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.'</span> <span class="o">%</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">u</span><span class="p">))</span>
1903 <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>
1904 <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1906 <span class="k">return</span> <span class="p">()</span>
1909 <span class="k">def</span> <span class="nf">stacky</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
1910 <span class="k">return</span> <span class="n">thing</span><span class="o">.</span><span class="vm">__class__</span> <span class="ow">in</span> <span class="p">{</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">}</span>
1913 <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">As</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>
1914 <span class="n">a</span>
1917 <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="p">,</span> <span class="n">s1</span><span class="p">)</span>
1920 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</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">2</span><span class="p">])</span>
1921 <span class="n">b</span>
1924 <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">s2</span><span class="p">)</span>
1927 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
1928 <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
1931 <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="o">-></span> <span class="p">(</span><span class="n">a1</span><span class="o">*</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">s2</span><span class="p">)</span>
1932 <span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a10001</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="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)}</span> <span class="o">-></span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span> <span class="p">(</span><span class="n">a10001</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span>
1935 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
1936 <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
1939 <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="o">-></span> <span class="p">(</span><span class="n">a1</span><span class="o">*</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">s2</span><span class="p">)</span>
1940 <span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a10002</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="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)}</span> <span class="o">-></span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span> <span class="p">(</span><span class="n">a10002</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span>
1943 <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="p">,</span> <span class="n">s1</span><span class="p">)</span> <span class="p">[</span><span class="n">a1</span><span class="o">*</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>
1945 <span class="p">(</span><span class="n">a1</span><span class="o">*</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="o">*</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">s2</span><span class="p">)</span> <span class="p">[</span><span class="n">a1</span><span class="p">]</span>
1947 <span class="p">(</span><span class="n">a1</span><span class="o">*</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="o">*</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="o">*</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="n">a1</span><span class="o">*</span><span class="p">]</span>
1950 <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">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>
1952 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">)</span>
1955 <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="n">n0</span><span class="p">)</span>
1958 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">f</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">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">N</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> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
1960 <span class="nb">print</span> <span class="n">doc_from_stack_effect</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">f</span><span class="p">)</span>
1963 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="n">n1</span> <span class="n">n2</span> <span class="n">n3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1966 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">sum_</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">):</span>
1967 <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">sum_</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1970 <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">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">n3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)))}</span> <span class="o">-></span> <span class="p">(</span><span class="n">n0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)</span>
1971 <span class="p">{</span><span class="n">n1</span><span class="p">:</span> <span class="n">n10001</span><span class="p">,</span> <span class="n">s1</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">n3</span><span class="p">,</span> <span class="n">s1</span><span class="p">))}</span> <span class="o">-></span> <span class="p">(</span><span class="n">n0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)</span>
1972 <span class="p">{</span><span class="n">n1</span><span class="p">:</span> <span class="n">n10001</span><span class="p">,</span> <span class="n">s1</span><span class="p">:</span> <span class="p">(</span><span class="n">n3</span><span class="p">,</span> <span class="n">s1</span><span class="p">),</span> <span class="n">n2</span><span class="p">:</span> <span class="n">n10002</span><span class="p">}</span> <span class="o">-></span> <span class="p">(</span><span class="n">n0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)</span>
1973 <span class="p">{</span><span class="n">n1</span><span class="p">:</span> <span class="n">n10001</span><span class="p">,</span> <span class="n">s1</span><span class="p">:</span> <span class="p">(</span><span class="n">n1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">),</span> <span class="n">n3</span><span class="p">:</span> <span class="n">n10003</span><span class="p">,</span> <span class="n">n2</span><span class="p">:</span> <span class="n">n10002</span><span class="p">}</span> <span class="o">-></span> <span class="p">(</span><span class="n">n0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)</span>
1977 <div class="section" id="compose-version-3">
1978 <h4><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 3<a class="headerlink" href="#compose-version-3" title="Permalink to this headline">¶</a></h4>
1979 <p>This function has to be modified to yield multiple results.</p>
1980 <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>
1981 <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>
1982 <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>
1983 <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
1984 <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">'Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.'</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>
1985 <span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
1986 <span class="k">yield</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">))</span>
1989 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">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>
1990 <span class="k">for</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">product</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
1991 <span class="k">try</span><span class="p">:</span>
1992 <span class="k">for</span> <span class="n">result</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>
1993 <span class="k">yield</span> <span class="n">result</span>
1994 <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
1995 <span class="k">pass</span>
1998 <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>
1999 <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>
2000 <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>
2001 <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
2004 <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>
2005 <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>
2008 <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>
2009 <span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
2012 <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>
2013 <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>
2016 <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>
2019 <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>
2020 <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>
2023 <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>
2024 <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>
2027 <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>
2028 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">cons</span><span class="p">),</span>
2029 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">),</span>
2031 <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>
2032 <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>
2035 <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>
2038 <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>
2039 <span class="n">a</span>
2042 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</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>
2045 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</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">2</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
2046 <span class="n">b</span>
2049 <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">s2</span><span class="p">))</span>
2052 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
2053 <span class="nb">print</span> <span class="n">result</span>
2056 <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">a4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="n">s1</span><span class="p">,</span> <span class="n">a2</span><span class="p">:</span> <span class="n">a3</span><span class="p">}</span>
2057 <span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a4</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="o">*</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">a2</span><span class="p">:</span> <span class="n">a10003</span><span class="p">}</span>
2060 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
2061 <span class="nb">print</span> <span class="n">result</span>
2064 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">s2</span><span class="p">:</span> <span class="n">s1</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="n">a1</span><span class="p">}</span>
2065 <span class="p">{</span><span class="n">s2</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</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">a2</span><span class="p">:</span> <span class="n">a10004</span><span class="p">,</span> <span class="n">a4</span><span class="p">:</span> <span class="n">a1</span><span class="p">}</span>
2071 <div class="section" id="part-vii-typing-combinators">
2072 <h2>Part VII: Typing Combinators<a class="headerlink" href="#part-vii-typing-combinators" title="Permalink to this headline">¶</a></h2>
2073 <p>In order to compute the stack effect of combinators you kinda have to
2074 have the quoted programs they expect available. In the most general
2075 case, the <code class="docutils literal notranslate"><span class="pre">i</span></code> combinator, you can’t say anything about its stack
2076 effect other than it expects one quote:</p>
2077 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">i</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="o">--</span> <span class="o">...</span> <span class="o">.</span><span class="mf">1.</span><span class="p">)</span>
2081 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">i</span> <span class="p">(</span><span class="o">...</span> <span class="p">[</span><span class="n">A</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="o">...</span> <span class="n">A</span><span class="o">*</span><span class="p">)</span>
2084 <p>Consider the type of:</p>
2085 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">cons</span><span class="p">]</span> <span class="n">dip</span>
2088 <p>Obviously it would be:</p>
2089 <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="mi">1</span><span class="p">]</span> <span class="n">a2</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">..</span><span class="mi">1</span><span class="p">]</span> <span class="n">a2</span><span class="p">)</span>
2092 <p><code class="docutils literal notranslate"><span class="pre">dip</span></code> itself could have:</p>
2093 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(a1 [..1] -- ... then what?
2096 <p>Without any information about the contents of the quote we can’t say
2097 much about the result.</p>
2098 <div class="section" id="hybrid-inferencer-interpreter">
2099 <h3>Hybrid Inferencer/Interpreter<a class="headerlink" href="#hybrid-inferencer-interpreter" title="Permalink to this headline">¶</a></h3>
2100 <p>I think there’s a way forward. If we convert our list (of terms we are
2101 composing) into a stack structure we can use it as a <em>Joy expression</em>,
2102 then we can treat the <em>output half</em> of a function’s stack effect comment
2103 as a Joy interpreter stack, and just execute combinators directly. We
2104 can hybridize the compostition function with an interpreter to evaluate
2105 combinators, compose non-combinator functions, and put type variables on
2106 the stack. For combinators like <code class="docutils literal notranslate"><span class="pre">branch</span></code> that can have more than one
2107 stack effect we have to “split universes” again and return both.</p>
2108 <div class="section" id="joy-types-for-functions">
2109 <h4>Joy Types for Functions<a class="headerlink" href="#joy-types-for-functions" title="Permalink to this headline">¶</a></h4>
2110 <p>We need a type variable for Joy functions that can go in our expressions
2111 and be used by the hybrid inferencer/interpreter. They have to store a
2112 name and a list of stack effects.</p>
2113 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">FunctionJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
2115 <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>
2116 <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
2117 <span class="bp">self</span><span class="o">.</span><span class="n">stack_effects</span> <span class="o">=</span> <span class="n">sec</span>
2118 <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
2120 <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
2121 <span class="k">return</span> <span class="bp">self</span>
2122 <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
2124 <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
2125 <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
2129 <div class="section" id="specialized-for-simple-functions-and-combinators">
2130 <h4>Specialized for Simple Functions and Combinators<a class="headerlink" href="#specialized-for-simple-functions-and-combinators" title="Permalink to this headline">¶</a></h4>
2131 <p>For non-combinator functions the stack effects list contains stack
2132 effect comments (represented by pairs of cons-lists as described above.)</p>
2133 <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">FunctionJoyType</span><span class="p">):</span>
2134 <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'F'</span>
2137 <p>For combinators the list contains Python functions.</p>
2138 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CombinatorJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
2140 <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'C'</span>
2142 <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="n">expect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
2143 <span class="nb">super</span><span class="p">(</span><span class="n">CombinatorJoyType</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</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>
2144 <span class="bp">self</span><span class="o">.</span><span class="n">expect</span> <span class="o">=</span> <span class="n">expect</span>
2146 <span class="k">def</span> <span class="nf">enter_guard</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
2147 <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">expect</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
2148 <span class="k">return</span> <span class="n">f</span>
2149 <span class="n">g</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">expect</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">expect</span>
2150 <span class="n">new_f</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</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="p">()))</span>
2151 <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">new_f</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">new_f</span><span class="p">)</span>
2152 <span class="k">return</span> <span class="n">new_f</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>
2155 <p>For simple combinators that have only one effect (like <code class="docutils literal notranslate"><span class="pre">dip</span></code>) you only
2156 need one function and it can be the combinator itself.</p>
2157 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">joy.library</span>
2159 <span class="n">dip</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">'dip'</span><span class="p">,</span> <span class="p">[</span><span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">dip</span><span class="p">],</span> <span class="mi">23</span><span class="p">)</span>
2162 <p>For combinators that can have more than one effect (like <code class="docutils literal notranslate"><span class="pre">branch</span></code>) you
2163 have to write functions that each implement the action of one of the
2165 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">branch_true</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>
2166 <span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
2167 <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">then</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
2169 <span class="k">def</span> <span class="nf">branch_false</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>
2170 <span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
2171 <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">else_</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
2173 <span class="n">branch</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">'branch'</span><span class="p">,</span> <span class="p">[</span><span class="n">branch_true</span><span class="p">,</span> <span class="n">branch_false</span><span class="p">],</span> <span class="mi">100</span><span class="p">)</span>
2176 <p>You can also provide an optional stack effect, input-side only, that
2177 will then be used as an identity function (that accepts and returns
2178 stacks that match the “guard” stack effect) which will be used to guard
2179 against type mismatches going into the evaluation of the combinator.</p>
2181 <div class="section" id="infer">
2182 <h4><code class="docutils literal notranslate"><span class="pre">infer()</span></code><a class="headerlink" href="#infer" title="Permalink to this headline">¶</a></h4>
2183 <p>With those in place, we can define a function that accepts a sequence of
2184 Joy type variables, including ones representing functions (not just
2185 values), and attempts to grind out all the possible stack effects of
2186 that expression.</p>
2187 <p>One tricky thing is that type variables <em>in the expression</em> have to be
2188 updated along with the stack effects after doing unification or we risk
2189 losing useful information. This was a straightforward, if awkward,
2190 modification to the call structure of <code class="docutils literal notranslate"><span class="pre">meta_compose()</span></code> et. al.</p>
2191 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ID</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="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># Identity function.</span>
2194 <span class="k">def</span> <span class="nf">infer</span><span class="p">(</span><span class="o">*</span><span class="n">expression</span><span class="p">):</span>
2195 <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">_infer</span><span class="p">(</span><span class="n">list_to_stack</span><span class="p">(</span><span class="n">expression</span><span class="p">))))</span>
2198 <span class="k">def</span> <span class="nf">_infer</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">F</span><span class="o">=</span><span class="n">ID</span><span class="p">):</span>
2199 <span class="n">_log_it</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
2200 <span class="k">if</span> <span class="ow">not</span> <span class="n">e</span><span class="p">:</span>
2201 <span class="k">return</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span>
2203 <span class="n">n</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">e</span>
2205 <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>
2206 <span class="n">eFG</span> <span class="o">=</span> <span class="n">meta_compose</span><span class="p">([</span><span class="n">F</span><span class="p">],</span> <span class="n">n</span><span class="o">.</span><span class="n">stack_effects</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
2207 <span class="n">res</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">_infer</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">Fn</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span><span class="p">,</span> <span class="n">Fn</span> <span class="ow">in</span> <span class="n">eFG</span><span class="p">)</span>
2209 <span class="k">elif</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>
2210 <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">n</span><span class="o">.</span><span class="n">enter_guard</span><span class="p">(</span><span class="n">F</span><span class="p">)</span>
2211 <span class="n">res</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">_interpret</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">,</span> <span class="n">e</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>
2213 <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">Symbol</span><span class="p">):</span>
2214 <span class="k">assert</span> <span class="n">n</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">FUNCTIONS</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
2215 <span class="n">func</span> <span class="o">=</span> <span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">_dictionary</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>
2216 <span class="n">res</span> <span class="o">=</span> <span class="n">_interpret</span><span class="p">(</span><span class="n">func</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="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>
2218 <span class="k">else</span><span class="p">:</span>
2219 <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">F</span>
2220 <span class="n">res</span> <span class="o">=</span> <span class="n">_infer</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">fo</span><span class="p">)))</span>
2222 <span class="k">return</span> <span class="n">res</span>
2225 <span class="k">def</span> <span class="nf">_interpret</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
2226 <span class="n">new_fo</span><span class="p">,</span> <span class="n">ee</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">fo</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="p">{})</span>
2227 <span class="n">ee</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">FUNCTIONS</span><span class="p">,</span> <span class="n">ee</span><span class="p">)</span> <span class="c1"># Fix Symbols.</span>
2228 <span class="n">new_F</span> <span class="o">=</span> <span class="n">fi</span><span class="p">,</span> <span class="n">new_fo</span>
2229 <span class="k">return</span> <span class="n">_infer</span><span class="p">(</span><span class="n">ee</span><span class="p">,</span> <span class="n">new_F</span><span class="p">)</span>
2232 <span class="k">def</span> <span class="nf">_log_it</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">F</span><span class="p">):</span>
2233 <span class="n">_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
2234 <span class="sa">u</span><span class="s1">'</span><span class="si">%3i</span><span class="s1"> </span><span class="si">%s</span><span class="s1"> ∘ </span><span class="si">%s</span><span class="s1">'</span><span class="p">,</span>
2235 <span class="nb">len</span><span class="p">(</span><span class="n">inspect_stack</span><span class="p">()),</span>
2236 <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>
2237 <span class="n">expression_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
2238 <span class="p">)</span>
2242 <div class="section" id="work-in-progress">
2243 <h4>Work in Progress<a class="headerlink" href="#work-in-progress" title="Permalink to this headline">¶</a></h4>
2244 <p>And that brings us to current Work-In-Progress. The mixed-mode
2245 inferencer/interpreter <code class="docutils literal notranslate"><span class="pre">infer()</span></code> function seems to work well. There
2246 are details I should document, and the rest of the code in the <code class="docutils literal notranslate"><span class="pre">types</span></code>
2247 module (FIXME link to its docs here!) should be explained… There is
2248 cruft to convert the definitions in <code class="docutils literal notranslate"><span class="pre">DEFS</span></code> to the new
2249 <code class="docutils literal notranslate"><span class="pre">SymbolJoyType</span></code> objects, and some combinators. Here is an example of
2250 output from the current code :</p>
2251 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span> <span class="c1"># (Don't try to run this cell! It's not going to work. This is "read only" code heh..)</span>
2253 <span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="nb">format</span><span class="o">=</span><span class="s1">'</span><span class="si">%(message)s</span><span class="s1">'</span><span class="p">,</span> <span class="n">stream</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
2255 <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">FUNCTIONS</span><span class="p">)</span>
2257 <span class="n">h</span> <span class="o">=</span> <span class="n">infer</span><span class="p">((</span><span class="n">pred</span><span class="p">,</span> <span class="n">s2</span><span class="p">),</span> <span class="p">(</span><span class="n">mul</span><span class="p">,</span> <span class="n">s3</span><span class="p">),</span> <span class="p">(</span><span class="n">div</span><span class="p">,</span> <span class="n">s4</span><span class="p">),</span> <span class="p">(</span><span class="n">nullary</span><span class="p">,</span> <span class="p">(</span><span class="nb">bool</span><span class="p">,</span> <span class="n">s5</span><span class="p">)),</span> <span class="n">dipd</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
2259 <span class="nb">print</span> <span class="s1">'-'</span> <span class="o">*</span> <span class="mi">40</span>
2261 <span class="k">for</span> <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="ow">in</span> <span class="n">h</span><span class="p">:</span>
2262 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
2265 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">---------------------------------------------------------------------------</span>
2267 <span class="ne">ZeroDivisionError</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>
2269 <span class="o"><</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">1</span><span class="o">-</span><span class="mi">9</span><span class="n">a9d60354c35</span><span class="o">></span> <span class="ow">in</span> <span class="o"><</span><span class="n">module</span><span class="o">></span><span class="p">()</span>
2270 <span class="o">----></span> <span class="mi">1</span> <span class="mi">1</span><span class="o">/</span><span class="mi">0</span> <span class="c1"># (Don't try to run this cell! It's not going to work. This is "read only" code heh..)</span>
2271 <span class="mi">2</span>
2272 <span class="mi">3</span> <span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="nb">format</span><span class="o">=</span><span class="s1">'</span><span class="si">%(message)s</span><span class="s1">'</span><span class="p">,</span> <span class="n">stream</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
2273 <span class="mi">4</span>
2274 <span class="mi">5</span> <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">FUNCTIONS</span><span class="p">)</span>
2277 <span class="ne">ZeroDivisionError</span><span class="p">:</span> <span class="n">integer</span> <span class="n">division</span> <span class="ow">or</span> <span class="n">modulo</span> <span class="n">by</span> <span class="n">zero</span>
2280 <p>The numbers at the start of the lines are the current depth of the
2281 Python call stack. They’re followed by the current computed stack effect
2282 (initialized to <code class="docutils literal notranslate"><span class="pre">ID</span></code>) then the pending expression (the inference of
2283 the stack effect of which is the whole object of the current example.)</p>
2284 <p>In this example we are implementing (and inferring) <code class="docutils literal notranslate"><span class="pre">ifte</span></code> as
2285 <code class="docutils literal notranslate"><span class="pre">[nullary</span> <span class="pre">bool]</span> <span class="pre">dipd</span> <span class="pre">branch</span></code> which shows off a lot of the current
2286 implementation in action.</p>
2287 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> 7 (--) ∘ [pred] [mul] [div] [nullary bool] dipd branch
2288 8 (-- [pred ...2]) ∘ [mul] [div] [nullary bool] dipd branch
2289 9 (-- [pred ...2] [mul ...3]) ∘ [div] [nullary bool] dipd branch
2290 10 (-- [pred ...2] [mul ...3] [div ...4]) ∘ [nullary bool] dipd branch
2291 11 (-- [pred ...2] [mul ...3] [div ...4] [nullary bool ...5]) ∘ dipd branch
2292 15 (-- [pred ...5]) ∘ nullary bool [mul] [div] branch
2293 19 (-- [pred ...2]) ∘ [stack] dinfrirst bool [mul] [div] branch
2294 20 (-- [pred ...2] [stack ]) ∘ dinfrirst bool [mul] [div] branch
2295 22 (-- [pred ...2] [stack ]) ∘ dip infra first bool [mul] [div] branch
2296 26 (--) ∘ stack [pred] infra first bool [mul] [div] branch
2297 29 (... -- ... [...]) ∘ [pred] infra first bool [mul] [div] branch
2298 30 (... -- ... [...] [pred ...1]) ∘ infra first bool [mul] [div] branch
2299 34 (--) ∘ pred s1 swaack first bool [mul] [div] branch
2300 37 (n1 -- n2) ∘ [n1] swaack first bool [mul] [div] branch
2301 38 (... n1 -- ... n2 [n1 ...]) ∘ swaack first bool [mul] [div] branch
2302 41 (... n1 -- ... n1 [n2 ...]) ∘ first bool [mul] [div] branch
2303 44 (n1 -- n1 n2) ∘ bool [mul] [div] branch
2304 47 (n1 -- n1 b1) ∘ [mul] [div] branch
2305 48 (n1 -- n1 b1 [mul ...1]) ∘ [div] branch
2306 49 (n1 -- n1 b1 [mul ...1] [div ...2]) ∘ branch
2317 ----------------------------------------
2328 <div class="section" id="conclusion">
2329 <h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this headline">¶</a></h2>
2330 <p>We built a simple type inferencer, and a kind of crude “compiler” for a
2331 subset of Joy functions. Then we built a more powerful inferencer that
2332 actually does some evaluation and explores branching code paths</p>
2333 <p>Work remains to be done:</p>
2335 <li>the rest of the library has to be covered</li>
2336 <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>
2337 <li>extend the types to check values (see the appendix)</li>
2338 <li>other kinds of “higher order” type variables, OR, AND, etc..</li>
2339 <li>maybe rewrite in Prolog for great good?</li>
2341 <li>don’t permit composition of functions that don’t compose</li>
2342 <li>auto-compile compilable functions</li>
2345 <li>Compiling more than just the Yin functions.</li>
2346 <li>getting better visibility (than Python debugger.)</li>
2347 <li>DOOOOCS!!!! Lots of docs!<ul>
2348 <li>docstrings all around</li>
2349 <li>improve this notebook (it kinda falls apart at the end
2350 narratively. I went off and just started writing code to see if it
2351 would work. It does, but now I have to come back and describe here
2357 <div class="section" id="appendix-joy-in-the-logical-paradigm">
2358 <h2>Appendix: Joy in the Logical Paradigm<a class="headerlink" href="#appendix-joy-in-the-logical-paradigm" title="Permalink to this headline">¶</a></h2>
2359 <p>For <em>type checking</em> to work the type label classes have to be modified
2360 to let <code class="docutils literal notranslate"><span class="pre">T</span> <span class="pre">>=</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>
2361 is <code class="docutils literal notranslate"><span class="pre">int</span></code>. If you do that you can take advantage of the <em>logical
2362 relational</em> nature of the stack effect comments to “compute in reverse”
2363 as it were. There’s a working demo of this at the end of the <code class="docutils literal notranslate"><span class="pre">types</span></code>
2364 module. But if you’re interested in all that you should just use Prolog!</p>
2365 <p>Anyhow, type <em>checking</em> is a few easy steps away.</p>
2366 <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>
2367 <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>
2368 <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">'accept'</span><span class="p">)</span>
2369 <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>
2371 <span class="n">AnyJoyType</span><span class="o">.</span><span class="fm">__ge__</span> <span class="o">=</span> <span class="n">_ge</span>
2372 <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>
2373 <span class="n">StackJoyType</span><span class="o">.</span><span class="n">accept</span> <span class="o">=</span> <span class="nb">tuple</span>
2383 <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
2384 <div class="sphinxsidebarwrapper">
2385 <h3><a href="../index.html">Table Of Contents</a></h3>
2387 <li><a class="reference internal" href="#">The Blissful Elegance of Typing Joy</a><ul>
2388 <li><a class="reference internal" href="#part-i-poials-rules">Part I: Pöial’s Rules</a><ul>
2389 <li><a class="reference internal" href="#first-rule">First Rule</a></li>
2390 <li><a class="reference internal" href="#second-rule">Second Rule</a></li>
2391 <li><a class="reference internal" href="#third-rule">Third Rule</a></li>
2392 <li><a class="reference internal" href="#stack-effect-comments">Stack Effect Comments</a></li>
2393 <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>
2394 <li><a class="reference internal" href="#popswap-roll"><code class="docutils literal notranslate"><span class="pre">pop∘swap</span> <span class="pre">roll<</span></code></a></li>
2395 <li><a class="reference internal" href="#compiling-popswaproll">Compiling <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<</span></code></a></li>
2396 <li><a class="reference internal" href="#functions-on-stacks">Functions on Stacks</a></li>
2397 <li><a class="reference internal" href="#popswaproll-rest"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<</span> <span class="pre">rest</span></code></a></li>
2398 <li><a class="reference internal" href="#popswaproll-rest-rest"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest</span> <span class="pre">rest</span></code></a></li>
2399 <li><a class="reference internal" href="#popswaproll-restrest-cons"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest∘rest</span> <span class="pre">cons</span></code></a></li>
2400 <li><a class="reference internal" href="#popswaproll-restrestcons-cons"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest∘rest∘cons</span> <span class="pre">cons</span></code></a></li>
2403 <li><a class="reference internal" href="#part-ii-implementation">Part II: Implementation</a><ul>
2404 <li><a class="reference internal" href="#representing-stack-effect-comments-in-python">Representing Stack Effect Comments in Python</a></li>
2405 <li><a class="reference internal" href="#compose"><code class="docutils literal notranslate"><span class="pre">compose()</span></code></a></li>
2406 <li><a class="reference internal" href="#unify"><code class="docutils literal notranslate"><span class="pre">unify()</span></code></a></li>
2407 <li><a class="reference internal" href="#update"><code class="docutils literal notranslate"><span class="pre">update()</span></code></a></li>
2408 <li><a class="reference internal" href="#relabel"><code class="docutils literal notranslate"><span class="pre">relabel()</span></code></a></li>
2409 <li><a class="reference internal" href="#delabel"><code class="docutils literal notranslate"><span class="pre">delabel()</span></code></a></li>
2410 <li><a class="reference internal" href="#c"><code class="docutils literal notranslate"><span class="pre">C()</span></code></a></li>
2411 <li><a class="reference internal" href="#stack-functions">Stack Functions</a></li>
2412 <li><a class="reference internal" href="#dealing-with-cons-and-uncons">Dealing with <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code></a><ul>
2413 <li><a class="reference internal" href="#unify-version-2"><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 2</a></li>
2418 <li><a class="reference internal" href="#part-iii-compiling-yin-functions">Part III: Compiling Yin Functions</a><ul>
2419 <li><a class="reference internal" href="#python-identifiers">Python Identifiers</a></li>
2420 <li><a class="reference internal" href="#doc-from-stack-effect"><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code></a></li>
2421 <li><a class="reference internal" href="#compile"><code class="docutils literal notranslate"><span class="pre">compile_()</span></code></a></li>
2422 <li><a class="reference internal" href="#compiling-library-functions">Compiling Library Functions</a></li>
2425 <li><a class="reference internal" href="#part-iv-types-and-subtypes-of-arguments">Part IV: Types and Subtypes of Arguments</a><ul>
2426 <li><a class="reference internal" href="#number-type">“Number” Type</a></li>
2427 <li><a class="reference internal" href="#distinguishing-numbers">Distinguishing Numbers</a></li>
2428 <li><a class="reference internal" href="#distinguishing-types">Distinguishing Types</a></li>
2429 <li><a class="reference internal" href="#typing-sqr">Typing <code class="docutils literal notranslate"><span class="pre">sqr</span></code></a></li>
2430 <li><a class="reference internal" href="#modifying-the-inferencer">Modifying the Inferencer</a><ul>
2431 <li><a class="reference internal" href="#delabel-version-2"><code class="docutils literal notranslate"><span class="pre">delabel()</span></code> version 2</a></li>
2432 <li><a class="reference internal" href="#unify-version-3"><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 3</a></li>
2433 <li><a class="reference internal" href="#compose-dup-and-mul">Compose <code class="docutils literal notranslate"><span class="pre">dup</span></code> and <code class="docutils literal notranslate"><span class="pre">mul</span></code></a></li>
2434 <li><a class="reference internal" href="#compile-version-2"><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 2</a></li>
2435 <li><a class="reference internal" href="#compilable"><code class="docutils literal notranslate"><span class="pre">compilable()</span></code></a></li>
2440 <li><a class="reference internal" href="#part-v-functions-that-use-the-stack">Part V: Functions that use the Stack</a><ul>
2441 <li><a class="reference internal" href="#stackuncons"><code class="docutils literal notranslate"><span class="pre">stack∘uncons</span></code></a></li>
2442 <li><a class="reference internal" href="#stackunconsuncons"><code class="docutils literal notranslate"><span class="pre">stack∘uncons∘uncons</span></code></a><ul>
2443 <li><a class="reference internal" href="#compose-version-2"><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 2</a></li>
2446 <li><a class="reference internal" href="#doc-from-stack-effect-version-2"><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code> version 2</a><ul>
2447 <li><a class="reference internal" href="#compile-version-3"><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 3</a></li>
2452 <li><a class="reference internal" href="#part-vi-multiple-stack-effects">Part VI: Multiple Stack Effects</a><ul>
2453 <li><a class="reference internal" href="#representing-an-unbounded-sequence-of-types">Representing an Unbounded Sequence of Types</a><ul>
2454 <li><a class="reference internal" href="#unify-version-4"><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 4</a></li>
2455 <li><a class="reference internal" href="#compose-version-3"><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 3</a></li>
2460 <li><a class="reference internal" href="#part-vii-typing-combinators">Part VII: Typing Combinators</a><ul>
2461 <li><a class="reference internal" href="#hybrid-inferencer-interpreter">Hybrid Inferencer/Interpreter</a><ul>
2462 <li><a class="reference internal" href="#joy-types-for-functions">Joy Types for Functions</a></li>
2463 <li><a class="reference internal" href="#specialized-for-simple-functions-and-combinators">Specialized for Simple Functions and Combinators</a></li>
2464 <li><a class="reference internal" href="#infer"><code class="docutils literal notranslate"><span class="pre">infer()</span></code></a></li>
2465 <li><a class="reference internal" href="#work-in-progress">Work in Progress</a></li>
2470 <li><a class="reference internal" href="#conclusion">Conclusion</a></li>
2471 <li><a class="reference internal" href="#appendix-joy-in-the-logical-paradigm">Appendix: Joy in the Logical Paradigm</a></li>
2475 <div class="relations">
2476 <h3>Related Topics</h3>
2478 <li><a href="../index.html">Documentation overview</a><ul>
2479 <li><a href="index.html">Essays about Programming in Joy</a><ul>
2480 <li>Previous: <a href="Zipper.html" title="previous chapter">Traversing Datastructures with Zippers</a></li>
2481 <li>Next: <a href="TypeChecking.html" title="next chapter">Type Checking</a></li>
2486 <div role="note" aria-label="source link">
2488 <ul class="this-page-menu">
2489 <li><a href="../_sources/notebooks/Types.rst.txt"
2490 rel="nofollow">Show Source</a></li>
2493 <div id="searchbox" style="display: none" role="search">
2494 <h3>Quick search</h3>
2495 <div class="searchformwrapper">
2496 <form class="search" action="../search.html" method="get">
2497 <input type="text" name="q" />
2498 <input type="submit" value="Go" />
2499 <input type="hidden" name="check_keywords" value="yes" />
2500 <input type="hidden" name="area" value="default" />
2504 <script type="text/javascript">$('#searchbox').show(0);</script>
2507 <div class="clearer"></div>
2509 <div class="footer" role="contentinfo">
2510 <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
2511 <img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
2514 <span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
2515 Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.