OSDN Git Service

233078748f26ceb341d5f5c63705a22cbab3b695
[joypy/Thun.git] / docs / sphinx_docs / _build / html / notebooks / Types.html
1
2 <!DOCTYPE html>
3
4 <html>
5   <head>
6     <meta charset="utf-8" />
7     <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
8
9     <title>The Blissful Elegance of Typing Joy &#8212; Thun 0.4.1 documentation</title>
10     <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
11     <link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
12     <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
13     <script src="../_static/jquery.js"></script>
14     <script src="../_static/underscore.js"></script>
15     <script src="../_static/doctools.js"></script>
16     <link rel="index" title="Index" href="../genindex.html" />
17     <link rel="search" title="Search" href="../search.html" />
18     <link rel="next" title="Type Checking" href="TypeChecking.html" />
19     <link rel="prev" title="Traversing Datastructures with Zippers" href="Zipper.html" />
20    
21   <link rel="stylesheet" href="../_static/custom.css" type="text/css" />
22   
23   
24   <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
25
26   </head><body>
27   
28
29     <div class="document">
30       <div class="documentwrapper">
31         <div class="bodywrapper">
32           
33
34           <div class="body" role="main">
35             
36   <section id="the-blissful-elegance-of-typing-joy">
37 <h1>The Blissful Elegance of Typing Joy<a class="headerlink" href="#the-blissful-elegance-of-typing-joy" title="Permalink to this headline">¶</a></h1>
38 <p>This notebook presents a simple type inferencer for Joy code. It can
39 infer the stack effect of most Joy expressions. It’s built largely by
40 means of existing ideas and research. (A great overview of the existing
41 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 Languages”</a>
43 given by Rob Kleffner on or about 2017-03-10 as part of a course on the
44 history of programming languages.)</p>
45 <p>The notebook starts with a simple inferencer based on the work of Jaanus
46 Pöial which we then progressively elaborate to cover more Joy semantics.
47 Along the way we write a simple “compiler” that emits Python code for
48 what I like to call Yin functions. (Yin functions are those that only
49 rearrange values in stacks, as opposed to Yang functions that actually
50 work on the values themselves.)</p>
51 <section id="part-i-poials-rules">
52 <h2>Part I: Pöial’s Rules<a class="headerlink" href="#part-i-poials-rules" title="Permalink to this headline">¶</a></h2>
53 <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 Pöial</a></p>
55 <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>
56     <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>
57     <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>
58     <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>
59     <span class="n">year</span> <span class="o">=</span> <span class="p">{</span><span class="mi">2006</span><span class="p">},</span>
60     <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>
61 <span class="p">}</span>
62 </pre></div>
63 </div>
64 <section id="first-rule">
65 <h3>First Rule<a class="headerlink" href="#first-rule" title="Permalink to this headline">¶</a></h3>
66 <p>This rule deals with functions (and literals) that put items on the
67 stack <code class="docutils literal notranslate"><span class="pre">(--</span> <span class="pre">d)</span></code>:</p>
68 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (a -- b)∘(-- d)
69 ---------------------
70      (a -- b d)
71 </pre></div>
72 </div>
73 </section>
74 <section id="second-rule">
75 <h3>Second Rule<a class="headerlink" href="#second-rule" title="Permalink to this headline">¶</a></h3>
76 <p>This rule deals with functions that consume items from the stack
77 <code class="docutils literal notranslate"><span class="pre">(a</span> <span class="pre">--)</span></code>:</p>
78 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (a --)∘(c -- d)
79 ---------------------
80      (c a -- d)
81 </pre></div>
82 </div>
83 </section>
84 <section id="third-rule">
85 <h3>Third Rule<a class="headerlink" href="#third-rule" title="Permalink to this headline">¶</a></h3>
86 <p>The third rule is actually two rules. These two rules deal with
87 composing functions when the second one will consume one of items the
88 first one produces. The two types must be
89 <a class="reference external" href="https://en.wikipedia.org/wiki/Robinson's_unification_algorithm">unified</a>
90 or a type conflict declared.</p>
91 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (a -- b t[i])∘(c u[j] -- d)   t &lt;= u (t is subtype of u)
92 -------------------------------
93    (a -- b     )∘(c      -- d)   t[i] == t[k] == u[j]
94                                          ^
95
96    (a -- b t[i])∘(c u[j] -- d)   u &lt;= t (u is subtype of t)
97 -------------------------------
98    (a -- b     )∘(c      -- d)   t[i] == u[k] == u[j]
99 </pre></div>
100 </div>
101 <p>Let’s work through some examples by hand to develop an intuition for the
102 algorithm.</p>
103 <p>There’s a function in one of the other notebooks.</p>
104 <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">&lt;</span> <span class="n">rest</span> <span class="n">rest</span> <span class="n">cons</span> <span class="n">cons</span>
105 </pre></div>
106 </div>
107 <p>It’s all “stack chatter” and list manipulation so we should be able to
108 deduce its type.</p>
109 </section>
110 <section id="stack-effect-comments">
111 <h3>Stack Effect Comments<a class="headerlink" href="#stack-effect-comments" title="Permalink to this headline">¶</a></h3>
112 <p>Joy function types will be represented by Forth-style stack effect
113 comments. I’m going to use numbers instead of names to keep track of the
114 stack arguments. (A little bit like <a class="reference external" href="https://en.wikipedia.org/wiki/De_Bruijn_index">De Bruijn
115 index</a>, at least it
116 reminds me of them):</p>
117 <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
119 <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
121 <span class="n">roll</span><span class="o">&lt;</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>
122 </pre></div>
123 </div>
124 <p>These commands alter the stack but don’t “look at” the values so these
125 numbers represent an “Any type”.</p>
126 </section>
127 <section id="pop-swap">
128 <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>
129 <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>
130 </pre></div>
131 </div>
132 <p>Here we encounter a complication. The argument numbers need to be made
133 unique among both sides. For this let’s change <code class="docutils literal notranslate"><span class="pre">pop</span></code> to use 0:</p>
134 <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>
135 </pre></div>
136 </div>
137 <p>Following the second rule:</p>
138 <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>
139 </pre></div>
140 </div>
141 </section>
142 <section id="popswap-roll">
143 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap</span> <span class="pre">roll&lt;</span></code><a class="headerlink" href="#popswap-roll" title="Permalink to this headline">¶</a></h3>
144 <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>
145 </pre></div>
146 </div>
147 <p>Let’s re-label them:</p>
148 <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>
149 </pre></div>
150 </div>
151 <p>Now we follow the rules.</p>
152 <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
153 terms in the forms:</p>
154 <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>
155                                             <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>
156 <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>
157                                             <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>
158 <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>
159 </pre></div>
160 </div>
161 <p>Here we must apply the second rule:</p>
162 <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>
163 <span class="o">-----------------------------------</span>
164      <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>
165 </pre></div>
166 </div>
167 <p>Now we de-label the type, uh, labels:</p>
168 <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
170 <span class="n">w</span><span class="o">/</span> <span class="p">{</span>
171     <span class="mi">1</span><span class="n">b</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
172     <span class="mi">3</span><span class="n">b</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
173     <span class="mi">2</span><span class="n">b</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
174     <span class="mi">0</span><span class="n">a</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
175     <span class="p">}</span>
176
177 <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>
178 </pre></div>
179 </div>
180 <p>And now we have the stack effect comment for <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;</span></code>.</p>
181 </section>
182 <section id="compiling-popswaproll">
183 <h3>Compiling <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;</span></code><a class="headerlink" href="#compiling-popswaproll" title="Permalink to this headline">¶</a></h3>
184 <p>The simplest way to “compile” this function would be something like:</p>
185 <div class="highlight-ipython2 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>
186     <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>
187 </pre></div>
188 </div>
189 <p>However, internally this function would still be allocating tuples
190 (stack cells) and doing other unnecesssary work.</p>
191 <p>Looking ahead for a moment, from the stack effect comment:</p>
192 <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>
193 </pre></div>
194 </div>
195 <p>We should be able to directly write out a Python function like:</p>
196 <div class="highlight-ipython2 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>
197     <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>
198     <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>
199 </pre></div>
200 </div>
201 <p>This eliminates the internal work of the first version. Because this
202 function only rearranges the stack and doesn’t do any actual processing
203 on the stack items themselves all the information needed to implement it
204 is in the stack effect comment.</p>
205 </section>
206 <section id="functions-on-stacks">
207 <h3>Functions on Stacks<a class="headerlink" href="#functions-on-stacks" title="Permalink to this headline">¶</a></h3>
208 <p>These are slightly tricky.</p>
209 <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
211 <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>
212 </pre></div>
213 </div>
214 </section>
215 <section id="popswaproll-rest">
216 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;</span> <span class="pre">rest</span></code><a class="headerlink" href="#popswaproll-rest" title="Permalink to this headline">¶</a></h3>
217 <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>
218 </pre></div>
219 </div>
220 <p>Re-label (instead of adding left and right tags I’m just taking the next
221 available index number for the right-side stack effect comment):</p>
222 <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>
223 </pre></div>
224 </div>
225 <p>Unify and update:</p>
226 <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>
227                                              <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>
228 <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>
229 </pre></div>
230 </div>
231 <p>Apply the first rule:</p>
232 <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>
233 <span class="o">---------------------------------------</span>
234      <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>
235 </pre></div>
236 </div>
237 <p>And there we are.</p>
238 </section>
239 <section id="popswaproll-rest-rest">
240 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest</span> <span class="pre">rest</span></code><a class="headerlink" href="#popswaproll-rest-rest" title="Permalink to this headline">¶</a></h3>
241 <p>Let’s do it again.</p>
242 <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>
243 </pre></div>
244 </div>
245 <p>Re-label (the tails of the lists on each side each get their own label):</p>
246 <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>
247 </pre></div>
248 </div>
249 <p>Unify and update (note the opening square brackets have been omited in
250 the substitution dict, this is deliberate and I’ll explain below):</p>
251 <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>
252                                                     <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>
253 <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>
254 </pre></div>
255 </div>
256 <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>
257 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
258 underlying structure of the Joy list is a cons-list in Python it’s
259 actually pretty easy. I’ll explain below.</p>
260 <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>
261 <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>
262 </pre></div>
263 </div>
264 <p>Giving us:</p>
265 <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>
266 </pre></div>
267 </div>
268 <p>From here we apply the first rule and get:</p>
269 <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>
270 </pre></div>
271 </div>
272 <p>Cleaning up the labels:</p>
273 <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>
274 </pre></div>
275 </div>
276 <p>This is the stack effect of <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest∘rest</span></code>.</p>
277 </section>
278 <section id="popswaproll-restrest-cons">
279 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest∘rest</span> <span class="pre">cons</span></code><a class="headerlink" href="#popswaproll-restrest-cons" title="Permalink to this headline">¶</a></h3>
280 <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>
281 </pre></div>
282 </div>
283 <p>Re-label:</p>
284 <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>
285 </pre></div>
286 </div>
287 <p>Unify:</p>
288 <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>
289                                                      <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>
290 <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>
291                                                      <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>
292 <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>
293 </pre></div>
294 </div>
295 <p>First rule:</p>
296 <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>
297 </pre></div>
298 </div>
299 <p>Re-label:</p>
300 <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>
301 </pre></div>
302 </div>
303 <p>Done.</p>
304 </section>
305 <section id="popswaproll-restrestcons-cons">
306 <h3><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest∘rest∘cons</span> <span class="pre">cons</span></code><a class="headerlink" href="#popswaproll-restrestcons-cons" title="Permalink to this headline">¶</a></h3>
307 <p>One more time.</p>
308 <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>
309 </pre></div>
310 </div>
311 <p>Re-label:</p>
312 <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>
313 </pre></div>
314 </div>
315 <p>Unify:</p>
316 <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>
317                                                        <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>
318 <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>
319                                                        <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>
320 <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>
321 </pre></div>
322 </div>
323 <p>First or second rule:</p>
324 <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>
325 </pre></div>
326 </div>
327 <p>Clean up the labels:</p>
328 <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>
329 </pre></div>
330 </div>
331 <p>And there you have it, the stack effect for
332 <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest∘rest∘cons∘cons</span></code>.</p>
333 <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>
334 </pre></div>
335 </div>
336 <p>From this stack effect comment it should be possible to construct the
337 following Python code:</p>
338 <div class="highlight-ipython2 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>
339     <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>
340     <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>
341 </pre></div>
342 </div>
343 </section>
344 </section>
345 <section id="part-ii-implementation">
346 <h2>Part II: Implementation<a class="headerlink" href="#part-ii-implementation" title="Permalink to this headline">¶</a></h2>
347 <section id="representing-stack-effect-comments-in-python">
348 <h3>Representing Stack Effect Comments in Python<a class="headerlink" href="#representing-stack-effect-comments-in-python" title="Permalink to this headline">¶</a></h3>
349 <p>I’m going to use pairs of tuples of type descriptors, which will be
350 integers or tuples of type descriptors:</p>
351 <div class="highlight-ipython2 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
353 <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
355 <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>
356 </pre></div>
357 </div>
358 </section>
359 <section id="compose">
360 <h3><code class="docutils literal notranslate"><span class="pre">compose()</span></code><a class="headerlink" href="#compose" title="Permalink to this headline">¶</a></h3>
361 <div class="highlight-ipython2 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
363     <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
365     <span class="c1"># First rule.</span>
366     <span class="c1">#</span>
367     <span class="c1">#       (a -- b) (-- d)</span>
368     <span class="c1">#    ---------------------</span>
369     <span class="c1">#         (a -- b d)</span>
370
371     <span class="k">if</span> <span class="ow">not</span> <span class="n">g_in</span><span class="p">:</span>
372
373         <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
375     <span class="c1"># Second rule.</span>
376     <span class="c1">#</span>
377     <span class="c1">#       (a --) (c -- d)</span>
378     <span class="c1">#    ---------------------</span>
379     <span class="c1">#         (c a -- d)</span>
380
381     <span class="k">elif</span> <span class="ow">not</span> <span class="n">f_out</span><span class="p">:</span>
382
383         <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
385     <span class="k">else</span><span class="p">:</span> <span class="c1"># Unify, update, recur.</span>
386
387         <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
389         <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
391         <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>
392             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">fo</span><span class="p">,</span> <span class="n">gi</span><span class="p">))</span>
393
394         <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
396         <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
398         <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
400     <span class="k">return</span> <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span>
401 </pre></div>
402 </div>
403 </section>
404 <section id="unify">
405 <h3><code class="docutils literal notranslate"><span class="pre">unify()</span></code><a class="headerlink" href="#unify" title="Permalink to this headline">¶</a></h3>
406 <div class="highlight-ipython2 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>
407     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
408         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
409
410     <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>
411         <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>
412     <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>
413         <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>
414     <span class="k">else</span><span class="p">:</span>
415         <span class="n">s</span> <span class="o">=</span> <span class="kc">False</span>
416
417     <span class="k">return</span> <span class="n">s</span>
418 </pre></div>
419 </div>
420 </section>
421 <section id="update">
422 <h3><code class="docutils literal notranslate"><span class="pre">update()</span></code><a class="headerlink" href="#update" title="Permalink to this headline">¶</a></h3>
423 <div class="highlight-ipython2 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>
424     <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>
425         <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>
426     <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>
427 </pre></div>
428 </div>
429 </section>
430 <section id="relabel">
431 <h3><code class="docutils literal notranslate"><span class="pre">relabel()</span></code><a class="headerlink" href="#relabel" title="Permalink to this headline">¶</a></h3>
432 <div class="highlight-ipython2 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>
433     <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
435 <span class="k">def</span> <span class="nf">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">):</span>
436     <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>
437         <span class="k">return</span> <span class="mi">1000</span> <span class="o">+</span> <span class="n">right</span>
438     <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
440 <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>
441 </pre></div>
442 </div>
443 <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>
444 </pre></div>
445 </div>
446 </section>
447 <section id="delabel">
448 <h3><code class="docutils literal notranslate"><span class="pre">delabel()</span></code><a class="headerlink" href="#delabel" title="Permalink to this headline">¶</a></h3>
449 <div class="highlight-ipython2 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>
450     <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>
451     <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
453 <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>
454     <span class="k">if</span> <span class="n">seen</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
455         <span class="n">seen</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
456     <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>
457         <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>
458     <span class="k">else</span><span class="p">:</span>
459         <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
460             <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>
461     <span class="k">return</span> <span class="n">seen</span>
462
463 <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>
464 </pre></div>
465 </div>
466 <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>
467 </pre></div>
468 </div>
469 </section>
470 <section id="c">
471 <h3><code class="docutils literal notranslate"><span class="pre">C()</span></code><a class="headerlink" href="#c" title="Permalink to this headline">¶</a></h3>
472 <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
473 stack effect comments and returns their composition (or raises and
474 exception if they can’t be composed due to type conflicts.)</p>
475 <div class="highlight-ipython2 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>
476     <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>
477     <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>
478     <span class="k">return</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
479 </pre></div>
480 </div>
481 <p>Let’s try it out.</p>
482 <div class="highlight-ipython2 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>
483 </pre></div>
484 </div>
485 <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>
486 </pre></div>
487 </div>
488 <div class="highlight-ipython2 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>
489 </pre></div>
490 </div>
491 <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>
492 </pre></div>
493 </div>
494 <div class="highlight-ipython2 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>
495 </pre></div>
496 </div>
497 <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>
498 </pre></div>
499 </div>
500 <div class="highlight-ipython2 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>
501 </pre></div>
502 </div>
503 <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>
504 </pre></div>
505 </div>
506 <div class="highlight-ipython2 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>
507 <span class="n">poswrd</span>
508 </pre></div>
509 </div>
510 <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>
511 </pre></div>
512 </div>
513 </section>
514 <section id="stack-functions">
515 <h3>Stack Functions<a class="headerlink" href="#stack-functions" title="Permalink to this headline">¶</a></h3>
516 <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
517 manipulate stacks. We use a cons-list of tuples and give the tails their
518 own numbers. Then everything above already works.</p>
519 <div class="highlight-ipython2 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
521 <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>
522 </pre></div>
523 </div>
524 <div class="highlight-ipython2 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>
525 </pre></div>
526 </div>
527 <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>
528 </pre></div>
529 </div>
530 <p>Compare this to the stack effect comment we wrote above:</p>
531 <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>
532 <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>
533 </pre></div>
534 </div>
535 <p>The translation table, if you will, would be:</p>
536 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
537 <span class="mi">3</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
538 <span class="mi">4</span><span class="p">:</span> <span class="o">...</span><span class="p">],</span>
539 <span class="mi">1</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
540 <span class="mi">2</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
541 <span class="mi">0</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
542 <span class="p">}</span>
543 </pre></div>
544 </div>
545 <div class="highlight-ipython2 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
547 <span class="n">F</span>
548 </pre></div>
549 </div>
550 <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>
551 </pre></div>
552 </div>
553 <p>Compare with the stack effect comment and you can see it works fine:</p>
554 <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>
555   <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>
556 </pre></div>
557 </div>
558 </section>
559 <section id="dealing-with-cons-and-uncons">
560 <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>
561 <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 work:</p>
563 <div class="highlight-ipython2 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>
564 </pre></div>
565 </div>
566 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
567     <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>
568 <span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
569     <span class="nb">print</span> <span class="n">e</span>
570 </pre></div>
571 </div>
572 <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>
573 </pre></div>
574 </div>
575 <section id="unify-version-2">
576 <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>
577 <p>The problem is that the <code class="docutils literal notranslate"><span class="pre">unify()</span></code> function as written doesn’t handle
578 the case when both terms are tuples. We just have to add a clause to
579 deal with this recursively:</p>
580 <div class="highlight-ipython2 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>
581     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
582         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
583     <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
584         <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>
585         <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
587     <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>
588         <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
590     <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>
591         <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
593     <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
595         <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>
596             <span class="c1"># Not a type error, caller passed in a bad value.</span>
597             <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
599         <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>
600         <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>
601         <span class="k">if</span> <span class="n">s</span> <span class="o">!=</span> <span class="kc">False</span><span class="p">:</span>
602             <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>
603     <span class="k">else</span><span class="p">:</span>
604         <span class="n">s</span> <span class="o">=</span> <span class="kc">False</span>
605
606     <span class="k">return</span> <span class="n">s</span>
607 </pre></div>
608 </div>
609 <div class="highlight-ipython2 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>
610 </pre></div>
611 </div>
612 <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>
613 </pre></div>
614 </div>
615 </section>
616 </section>
617 </section>
618 <section id="part-iii-compiling-yin-functions">
619 <h2>Part III: Compiling Yin Functions<a class="headerlink" href="#part-iii-compiling-yin-functions" title="Permalink to this headline">¶</a></h2>
620 <p>Now consider the Python function we would like to derive:</p>
621 <div class="highlight-ipython2 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>
622     <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>
623     <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>
624 </pre></div>
625 </div>
626 <p>And compare it to the input stack effect comment tuple we just computed:</p>
627 <div class="highlight-ipython2 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>
628 </pre></div>
629 </div>
630 <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>
631 </pre></div>
632 </div>
633 <p>The stack-de-structuring tuple has nearly the same form as our input
634 stack effect comment tuple, just in the reverse order:</p>
635 <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>
636 </pre></div>
637 </div>
638 <p>Remove the punctuation:</p>
639 <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>
640 </pre></div>
641 </div>
642 <p>Reverse the order and compare:</p>
643 <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>
644 <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>
645 </pre></div>
646 </div>
647 <p>Eh?</p>
648 <p>And the return tuple</p>
649 <div class="highlight-ipython2 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>
650 </pre></div>
651 </div>
652 <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>
653 </pre></div>
654 </div>
655 <p>is similar to the output stack effect comment tuple:</p>
656 <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>
657 <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>
658 </pre></div>
659 </div>
660 <p>This should make it pretty easy to write a Python function that accepts
661 the stack effect comment tuples and returns a new Python function
662 (either as a string of code or a function object ready to use) that
663 performs the semantics of that Joy function (described by the stack
664 effect.)</p>
665 <section id="python-identifiers">
666 <h3>Python Identifiers<a class="headerlink" href="#python-identifiers" title="Permalink to this headline">¶</a></h3>
667 <p>We want to substitute Python identifiers for the integers. I’m going to
668 repurpose <code class="docutils literal notranslate"><span class="pre">joy.parser.Symbol</span></code> class for this:</p>
669 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
670 <span class="kn">from</span> <span class="nn">joy.parser</span> <span class="kn">import</span> <span class="n">Symbol</span>
671
672
673 <span class="k">def</span> <span class="nf">_names_for</span><span class="p">():</span>
674     <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>
675     <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">&#39;a</span><span class="si">%i</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="nb">next</span><span class="p">(</span><span class="n">I</span><span class="p">))</span>
676
677
678 <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>
679     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
680         <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>
681     <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>
682         <span class="k">return</span> <span class="n">s</span><span class="p">[</span><span class="n">term</span><span class="p">]</span>
683     <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>
684 </pre></div>
685 </div>
686 </section>
687 <section id="doc-from-stack-effect">
688 <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>
689 <p>As a convenience I’ve implemented a function to convert the Python stack
690 effect comment tuples to reasonable text format. There are some details
691 in how this code works that related to stuff later in the notebook, so
692 you should skip it for now and read it later if you’re interested.</p>
693 <div class="highlight-ipython2 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>
694     <span class="k">return</span> <span class="s1">&#39;(</span><span class="si">%s</span><span class="s1">--</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span>
695         <span class="s1">&#39; &#39;</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">&#39;&#39;</span><span class="p">,))),</span>
696         <span class="s1">&#39; &#39;</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">&#39;&#39;</span><span class="p">,)</span> <span class="o">+</span> <span class="n">outputs</span><span class="p">))</span>
697     <span class="p">)</span>
698
699
700 <span class="k">def</span> <span class="nf">_to_str</span><span class="p">(</span><span class="n">term</span><span class="p">):</span>
701     <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>
702         <span class="k">try</span><span class="p">:</span>
703             <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">&#39;s&#39;</span>
704         <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
705             <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
706         <span class="k">return</span> <span class="s1">&#39;[.</span><span class="si">%i</span><span class="s1">.]&#39;</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
708     <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
709     <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>
710         <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
711         <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
713     <span class="k">try</span><span class="p">:</span>
714         <span class="n">n</span> <span class="o">=</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
715     <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
716         <span class="n">n</span> <span class="o">=</span> <span class="n">term</span>
717     <span class="k">else</span><span class="p">:</span>
718         <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">&#39;s&#39;</span><span class="p">:</span>
719             <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Stack label: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">term</span><span class="p">,))</span>
720
721     <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;.</span><span class="si">%s</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,))</span>
722     <span class="k">return</span> <span class="s1">&#39;[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
723 </pre></div>
724 </div>
725 </section>
726 <section id="compile">
727 <h3><code class="docutils literal notranslate"><span class="pre">compile_()</span></code><a class="headerlink" href="#compile" title="Permalink to this headline">¶</a></h3>
728 <p>Now we can write a compiler function to emit Python source code. (The
729 underscore suffix distiguishes it from the built-in <code class="docutils literal notranslate"><span class="pre">compile()</span></code>
730 function.)</p>
731 <div class="highlight-ipython2 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>
732     <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
733         <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>
734     <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>
735     <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">&#39;stack&#39;</span><span class="p">)</span>
736     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">inputs</span><span class="p">:</span>
737         <span class="n">i</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">i</span>
738     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">outputs</span><span class="p">:</span>
739         <span class="n">o</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">o</span>
740     <span class="k">return</span> <span class="s1">&#39;&#39;&#39;def </span><span class="si">%s</span><span class="s1">(stack):</span>
741 <span class="s1">    &quot;&quot;&quot;</span><span class="si">%s</span><span class="s1">&quot;&quot;&quot;</span>
742 <span class="s1">    </span><span class="si">%s</span><span class="s1"> = stack</span>
743 <span class="s1">    return </span><span class="si">%s</span><span class="s1">&#39;&#39;&#39;</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>
744 </pre></div>
745 </div>
746 <p>Here it is in action:</p>
747 <div class="highlight-ipython2 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">&#39;F&#39;</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
748
749 <span class="nb">print</span> <span class="n">source</span>
750 </pre></div>
751 </div>
752 <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>
753     <span class="sd">&quot;&quot;&quot;([3 4 .5.] 1 2 0 -- [2 1 .5.])&quot;&quot;&quot;</span>
754     <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>
755     <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>
756 </pre></div>
757 </div>
758 <p>Compare:</p>
759 <div class="highlight-ipython2 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>
760     <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>
761     <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>
762 </pre></div>
763 </div>
764 <p>Next steps:</p>
765 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="p">{}</span>
766
767 <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">&#39;__main__&#39;</span><span class="p">,</span> <span class="s1">&#39;single&#39;</span><span class="p">),</span> <span class="p">{},</span> <span class="n">L</span><span class="p">)</span>
768
769 <span class="n">L</span><span class="p">[</span><span class="s1">&#39;F&#39;</span><span class="p">]</span>
770 </pre></div>
771 </div>
772 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">function</span> <span class="n">F</span><span class="o">&gt;</span>
773 </pre></div>
774 </div>
775 <p>Let’s try it out:</p>
776 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">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>
777 <span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">SimpleFunctionWrapper</span>
778 </pre></div>
779 </div>
780 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">&#39;F&#39;</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">&#39;F&#39;</span><span class="p">])</span>
781 </pre></div>
782 </div>
783 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[4 5 ...] 2 3 1 F&#39;</span><span class="p">)</span>
784 </pre></div>
785 </div>
786 <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>
787 </pre></div>
788 </div>
789 <p>With this, we have a partial Joy compiler that works on the subset of
790 Joy functions that manipulate stacks (both what I call “stack chatter”
791 and the ones that manipulate stacks on the stack.)</p>
792 <p>I’m probably going to modify the definition wrapper code to detect
793 definitions that can be compiled by this partial compiler and do it
794 automatically. It might be a reasonable idea to detect sequences of
795 compilable functions in definitions that have uncompilable functions in
796 them and just compile those. However, if your library is well-factored
797 this might be less helpful.</p>
798 </section>
799 <section id="compiling-library-functions">
800 <h3>Compiling Library Functions<a class="headerlink" href="#compiling-library-functions" title="Permalink to this headline">¶</a></h3>
801 <p>We can use <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> to generate many primitives in the library
802 from their stack effect comments:</p>
803 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
804
805     <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
807     <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
809     <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
811     <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
813     <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
815     <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
817     <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
819     <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
821     <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
823     <span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
824 </pre></div>
825 </div>
826 <div class="highlight-ipython2 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>
827     <span class="nb">print</span>
828     <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>
829     <span class="nb">print</span>
830 </pre></div>
831 </div>
832 <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>
833     <span class="sd">&quot;&quot;&quot;(1 2 -- [1 .2.])&quot;&quot;&quot;</span>
834     <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>
835     <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>
836
837
838 <span class="k">def</span> <span class="nf">pop</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
839     <span class="sd">&quot;&quot;&quot;(1 --)&quot;&quot;&quot;</span>
840     <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>
841     <span class="k">return</span> <span class="n">stack</span>
842
843
844 <span class="k">def</span> <span class="nf">rest</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
845     <span class="sd">&quot;&quot;&quot;([1 .2.] -- 2)&quot;&quot;&quot;</span>
846     <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>
847     <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>
848
849
850 <span class="k">def</span> <span class="nf">rolldown</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
851     <span class="sd">&quot;&quot;&quot;(1 2 3 -- 2 3 1)&quot;&quot;&quot;</span>
852     <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>
853     <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>
854
855
856 <span class="k">def</span> <span class="nf">rollup</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
857     <span class="sd">&quot;&quot;&quot;(1 2 3 -- 3 1 2)&quot;&quot;&quot;</span>
858     <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>
859     <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>
860
861
862 <span class="k">def</span> <span class="nf">rrest</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
863     <span class="sd">&quot;&quot;&quot;([0 1 .2.] -- 2)&quot;&quot;&quot;</span>
864     <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>
865     <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>
866
867
868 <span class="k">def</span> <span class="nf">swap</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
869     <span class="sd">&quot;&quot;&quot;(1 2 -- 2 1)&quot;&quot;&quot;</span>
870     <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>
871     <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>
872
873
874 <span class="k">def</span> <span class="nf">swons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
875     <span class="sd">&quot;&quot;&quot;(0 1 -- [1 .0.])&quot;&quot;&quot;</span>
876     <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>
877     <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>
878
879
880 <span class="k">def</span> <span class="nf">uncons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
881     <span class="sd">&quot;&quot;&quot;([1 .2.] -- 1 2)&quot;&quot;&quot;</span>
882     <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>
883     <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>
884 </pre></div>
885 </div>
886 </section>
887 </section>
888 <section id="part-iv-types-and-subtypes-of-arguments">
889 <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>
890 <p>So far we have dealt with types of functions, those dealing with simple
891 stack manipulation. Let’s extend our machinery to deal with types of
892 arguments.</p>
893 <section id="number-type">
894 <h3>“Number” Type<a class="headerlink" href="#number-type" title="Permalink to this headline">¶</a></h3>
895 <p>Consider the definition of <code class="docutils literal notranslate"><span class="pre">sqr</span></code>:</p>
896 <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>
897 </pre></div>
898 </div>
899 <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>
900 <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>
901 </pre></div>
902 </div>
903 <p>And <code class="docutils literal notranslate"><span class="pre">mul</span></code> accepts two “numbers” (we’re ignoring ints vs. floats
904 vs. complex, etc., for now) and returns just one:</p>
905 <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>
906 </pre></div>
907 </div>
908 <p>So we’re composing:</p>
909 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(1 -- 1 1)∘(n n -- n)
910 </pre></div>
911 </div>
912 <p>The rules say we unify 1 with <code class="docutils literal notranslate"><span class="pre">n</span></code>:</p>
913 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (1 -- 1 1)∘(n n -- n)
914 ---------------------------  w/  {1: n}
915    (1 -- 1  )∘(n   -- n)
916 </pre></div>
917 </div>
918 <p>This involves detecting that “Any type” arguments can accept “numbers”.
919 If we were composing these functions the other way round this is still
920 the case:</p>
921 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (n n -- n)∘(1 -- 1 1)
922 ---------------------------  w/  {1: n}
923    (n n --  )∘(  -- n n)
924 </pre></div>
925 </div>
926 <p>The important thing here is that the mapping is going the same way in
927 both cases, from the “any” integer to the number</p>
928 </section>
929 <section id="distinguishing-numbers">
930 <h3>Distinguishing Numbers<a class="headerlink" href="#distinguishing-numbers" title="Permalink to this headline">¶</a></h3>
931 <p>We should also mind that the number that <code class="docutils literal notranslate"><span class="pre">mul</span></code> produces is not
932 (necessarily) the same as either of its inputs, which are not
933 (necessarily) the same as each other:</p>
934 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>mul (n2 n1 -- n3)
935
936
937    (1  -- 1  1)∘(n2 n1 -- n3)
938 --------------------------------  w/  {1: n2}
939    (n2 -- n2  )∘(n2    -- n3)
940
941
942    (n2 n1 -- n3)∘(1 -- 1  1 )
943 --------------------------------  w/  {1: n3}
944    (n2 n1 --   )∘(  -- n3 n3)
945 </pre></div>
946 </div>
947 </section>
948 <section id="distinguishing-types">
949 <h3>Distinguishing Types<a class="headerlink" href="#distinguishing-types" title="Permalink to this headline">¶</a></h3>
950 <p>So we need separate domains of “any” numbers and “number” numbers, and
951 we need to be able to ask the order of these domains. Now the notes on
952 the right side of rule three make more sense, eh?</p>
953 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (a -- b t[i])∘(c u[j] -- d)   t &lt;= u (t is subtype of u)
954 -------------------------------
955    (a -- b     )∘(c      -- d)   t[i] == t[k] == u[j]
956                                          ^
957
958    (a -- b t[i])∘(c u[j] -- d)   u &lt;= t (u is subtype of t)
959 -------------------------------
960    (a -- b     )∘(c      -- d)   t[i] == u[k] == u[j]
961 </pre></div>
962 </div>
963 <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
964 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>
965 <p>By creative use of Python’s “double underscore” methods we can define a
966 Python class hierarchy of Joy types and use the <code class="docutils literal notranslate"><span class="pre">issubclass()</span></code> method
967 to establish domain ordering, as well as other handy behaviour that will
968 make it fairly easy to reuse most of the code above.</p>
969 <div class="highlight-ipython2 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
971     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;a&#39;</span>
972
973     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
974         <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
975
976     <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
977         <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
979     <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
980         <span class="k">return</span> <span class="p">(</span>
981             <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>
982             <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>
983             <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>
984         <span class="p">)</span>
985
986     <span class="k">def</span> <span class="fm">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
987         <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
989     <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
990         <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>
991     <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
992
993     <span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
994         <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>
995
996
997 <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">&#39;n&#39;</span>
998 <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">&#39;f&#39;</span>
999 <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">&#39;i&#39;</span>
1000
1001
1002 <span class="k">class</span> <span class="nc">StackJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
1003     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;s&#39;</span>
1004
1005
1006 <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>
1007 <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>
1008 <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>
1009 <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>
1010 </pre></div>
1011 </div>
1012 <p>Mess with it a little:</p>
1013 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">permutations</span>
1014 </pre></div>
1015 </div>
1016 <p>“Any” types can be specialized to numbers and stacks, but not vice
1017 versa:</p>
1018 <div class="highlight-ipython2 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>
1019     <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="n">a</span> <span class="o">&gt;=</span> <span class="n">b</span>
1020 </pre></div>
1021 </div>
1022 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a0</span> <span class="o">&gt;=</span> <span class="n">n0</span> <span class="o">-&gt;</span> <span class="kc">True</span>
1023 <span class="n">a0</span> <span class="o">&gt;=</span> <span class="n">s0</span> <span class="o">-&gt;</span> <span class="kc">True</span>
1024 <span class="n">n0</span> <span class="o">&gt;=</span> <span class="n">a0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1025 <span class="n">n0</span> <span class="o">&gt;=</span> <span class="n">s0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1026 <span class="n">s0</span> <span class="o">&gt;=</span> <span class="n">a0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1027 <span class="n">s0</span> <span class="o">&gt;=</span> <span class="n">n0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1028 </pre></div>
1029 </div>
1030 <p>Our crude <a class="reference external" href="https://en.wikipedia.org/wiki/Numerical_tower">Numerical
1031 Tower</a> of <em>numbers</em> &gt;
1032 <em>floats</em> &gt; <em>integers</em> works as well (but we’re not going to use it yet):</p>
1033 <div class="highlight-ipython2 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>
1034     <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">&#39;&gt;=&#39;</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</span><span class="p">,</span> <span class="n">a</span> <span class="o">&gt;=</span> <span class="n">b</span>
1035 </pre></div>
1036 </div>
1037 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a0</span> <span class="o">&gt;=</span> <span class="n">n0</span> <span class="o">-&gt;</span> <span class="kc">True</span>
1038 <span class="n">a0</span> <span class="o">&gt;=</span> <span class="n">f0</span> <span class="o">-&gt;</span> <span class="kc">True</span>
1039 <span class="n">a0</span> <span class="o">&gt;=</span> <span class="n">i0</span> <span class="o">-&gt;</span> <span class="kc">True</span>
1040 <span class="n">n0</span> <span class="o">&gt;=</span> <span class="n">a0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1041 <span class="n">n0</span> <span class="o">&gt;=</span> <span class="n">f0</span> <span class="o">-&gt;</span> <span class="kc">True</span>
1042 <span class="n">n0</span> <span class="o">&gt;=</span> <span class="n">i0</span> <span class="o">-&gt;</span> <span class="kc">True</span>
1043 <span class="n">f0</span> <span class="o">&gt;=</span> <span class="n">a0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1044 <span class="n">f0</span> <span class="o">&gt;=</span> <span class="n">n0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1045 <span class="n">f0</span> <span class="o">&gt;=</span> <span class="n">i0</span> <span class="o">-&gt;</span> <span class="kc">True</span>
1046 <span class="n">i0</span> <span class="o">&gt;=</span> <span class="n">a0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1047 <span class="n">i0</span> <span class="o">&gt;=</span> <span class="n">n0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1048 <span class="n">i0</span> <span class="o">&gt;=</span> <span class="n">f0</span> <span class="o">-&gt;</span> <span class="kc">False</span>
1049 </pre></div>
1050 </div>
1051 </section>
1052 <section id="typing-sqr">
1053 <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>
1054 <div class="highlight-ipython2 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
1056 <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>
1057 </pre></div>
1058 </div>
1059 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span>
1060 </pre></div>
1061 </div>
1062 <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>
1063 </pre></div>
1064 </div>
1065 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span>
1066 </pre></div>
1067 </div>
1068 <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>
1069 </pre></div>
1070 </div>
1071 </section>
1072 <section id="modifying-the-inferencer">
1073 <h3>Modifying the Inferencer<a class="headerlink" href="#modifying-the-inferencer" title="Permalink to this headline">¶</a></h3>
1074 <p>Re-labeling still works fine:</p>
1075 <div class="highlight-ipython2 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
1077 <span class="n">foo</span>
1078 </pre></div>
1079 </div>
1080 <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>
1081 </pre></div>
1082 </div>
1083 <section id="delabel-version-2">
1084 <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>
1085 <p>The <code class="docutils literal notranslate"><span class="pre">delabel()</span></code> function needs an overhaul. It now has to keep track
1086 of how many labels of each domain it has “seen”.</p>
1087 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
1088
1089
1090 <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>
1091     <span class="k">if</span> <span class="n">seen</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1092         <span class="k">assert</span> <span class="n">c</span> <span class="ow">is</span> <span class="kc">None</span>
1093         <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
1095     <span class="k">try</span><span class="p">:</span>
1096         <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
1097     <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
1098         <span class="k">pass</span>
1099
1100     <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>
1101         <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>
1102         <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>
1103         <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
1104
1105     <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>
1106 </pre></div>
1107 </div>
1108 <div class="highlight-ipython2 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>
1109 </pre></div>
1110 </div>
1111 <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>
1112 </pre></div>
1113 </div>
1114 </section>
1115 <section id="unify-version-3">
1116 <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>
1117 <div class="highlight-ipython2 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>
1118     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1119         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
1120     <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
1121         <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>
1122         <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
1124     <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
1125         <span class="k">return</span> <span class="n">s</span>
1126
1127     <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>
1128         <span class="k">if</span> <span class="n">u</span> <span class="o">&gt;=</span> <span class="n">v</span><span class="p">:</span>
1129             <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>
1130             <span class="k">return</span> <span class="n">s</span>
1131         <span class="k">if</span> <span class="n">v</span> <span class="o">&gt;=</span> <span class="n">u</span><span class="p">:</span>
1132             <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>
1133             <span class="k">return</span> <span class="n">s</span>
1134         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
1135
1136     <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>
1137         <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>
1138             <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>
1139         <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>
1140             <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>
1141             <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>
1142                 <span class="k">break</span>
1143         <span class="k">return</span> <span class="n">s</span>
1144
1145     <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>
1146         <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>
1147             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
1148         <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>
1149         <span class="k">return</span> <span class="n">s</span>
1150
1151     <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>
1152         <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>
1153             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">u</span><span class="p">))</span>
1154         <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>
1155         <span class="k">return</span> <span class="n">s</span>
1156
1157     <span class="k">return</span> <span class="kc">False</span>
1158
1159
1160 <span class="k">def</span> <span class="nf">stacky</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
1161     <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>
1162 </pre></div>
1163 </div>
1164 <p>Rewrite the stack effect comments:</p>
1165 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
1166
1167     <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
1169     <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
1171     <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
1173     <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
1175     <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
1177     <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
1179     <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
1181     <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
1183     <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
1185     <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
1187     <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
1189     <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
1191     <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
1193     <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
1195     <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
1197     <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
1199     <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
1201     <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
1203     <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
1205     <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
1207     <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
1209     <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
1211     <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
1213     <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
1215     <span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
1216 </pre></div>
1217 </div>
1218 <div class="highlight-ipython2 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>
1219 </pre></div>
1220 </div>
1221 <div class="highlight-ipython2 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>
1222     <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
1223 </pre></div>
1224 </div>
1225 <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>
1226 <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>
1227 <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>
1228 <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>
1229 <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>
1230 <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>
1231 <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>
1232 <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>
1233 <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>
1234 <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>
1235 <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>
1236 <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>
1237 <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>
1238 <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>
1239 <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>
1240 <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>
1241 <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>
1242 <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>
1243 <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>
1244 <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>
1245 <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>
1246 <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>
1247 <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>
1248 <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>
1249 <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>
1250 <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>
1251 </pre></div>
1252 </div>
1253 <div class="highlight-ipython2 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>
1254 </pre></div>
1255 </div>
1256 </section>
1257 <section id="compose-dup-and-mul">
1258 <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>
1259 <div class="highlight-ipython2 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>
1260 </pre></div>
1261 </div>
1262 <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>
1263 </pre></div>
1264 </div>
1265 <p>Revisit the <code class="docutils literal notranslate"><span class="pre">F</span></code> function, works fine.</p>
1266 <div class="highlight-ipython2 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>
1267 <span class="n">F</span>
1268 </pre></div>
1269 </div>
1270 <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>
1271 </pre></div>
1272 </div>
1273 <div class="highlight-ipython2 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>
1274 </pre></div>
1275 </div>
1276 <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>
1277 </pre></div>
1278 </div>
1279 <p>Some otherwise inefficient functions are no longer to be feared. We can
1280 also get the effect of combinators in some limited cases.</p>
1281 <div class="highlight-ipython2 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>
1282     <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>
1283 </pre></div>
1284 </div>
1285 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [swap] dip</span>
1286 <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>
1287 </pre></div>
1288 </div>
1289 <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>
1290 </pre></div>
1291 </div>
1292 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [popop] dipd</span>
1293 <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>
1294 </pre></div>
1295 </div>
1296 <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>
1297 </pre></div>
1298 </div>
1299 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Reverse the order of the top three items.</span>
1300 <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>
1301 </pre></div>
1302 </div>
1303 <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>
1304 </pre></div>
1305 </div>
1306 </section>
1307 <section id="compile-version-2">
1308 <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>
1309 <p>Because the type labels represent themselves as valid Python identifiers
1310 the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function doesn’t need to generate them anymore:</p>
1311 <div class="highlight-ipython2 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>
1312     <span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">f</span>
1313     <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1314         <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>
1315     <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">&#39;stack&#39;</span><span class="p">)</span>
1316     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">inputs</span><span class="p">:</span>
1317         <span class="n">i</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">i</span>
1318     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">outputs</span><span class="p">:</span>
1319         <span class="n">o</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">o</span>
1320     <span class="k">return</span> <span class="s1">&#39;&#39;&#39;def </span><span class="si">%s</span><span class="s1">(stack):</span>
1321 <span class="s1">    &quot;&quot;&quot;</span><span class="si">%s</span><span class="s1">&quot;&quot;&quot;</span>
1322 <span class="s1">    </span><span class="si">%s</span><span class="s1"> = stack</span>
1323 <span class="s1">    return </span><span class="si">%s</span><span class="s1">&#39;&#39;&#39;</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>
1324 </pre></div>
1325 </div>
1326 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;F&#39;</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
1327 </pre></div>
1328 </div>
1329 <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>
1330     <span class="sd">&quot;&quot;&quot;([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])&quot;&quot;&quot;</span>
1331     <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>
1332     <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>
1333 </pre></div>
1334 </div>
1335 <p>But it cannot magically create new functions that involve e.g. math and
1336 such. Note that this is <em>not</em> a <code class="docutils literal notranslate"><span class="pre">sqr</span></code> function implementation:</p>
1337 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;sqr&#39;</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>
1338 </pre></div>
1339 </div>
1340 <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>
1341     <span class="sd">&quot;&quot;&quot;(n1 -- n2)&quot;&quot;&quot;</span>
1342     <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>
1343     <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>
1344 </pre></div>
1345 </div>
1346 <p>(Eventually I should come back around to this becuase it’s not tooo
1347 difficult to exend this code to be able to compile e.g.
1348 <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
1349 insert it in the right place. It requires a little more support from the
1350 library functions, in that we need to know to call <code class="docutils literal notranslate"><span class="pre">mul()</span></code> the Python
1351 function for <code class="docutils literal notranslate"><span class="pre">mul</span></code> the Joy function, but since <em>most</em> of the math
1352 functions (at least) are already wrappers it should be straightforward.)</p>
1353 </section>
1354 <section id="compilable">
1355 <h4><code class="docutils literal notranslate"><span class="pre">compilable()</span></code><a class="headerlink" href="#compilable" title="Permalink to this headline">¶</a></h4>
1356 <p>The functions that <em>can</em> be compiled are the ones that have only
1357 <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
1358 comments. We can write a function to check that:</p>
1359 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">imap</span>
1360
1361
1362 <span class="k">def</span> <span class="nf">compilable</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
1363     <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>
1364 </pre></div>
1365 </div>
1366 <div class="highlight-ipython2 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>
1367     <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>
1368         <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
1369 </pre></div>
1370 </div>
1371 <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>
1372 <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>
1373 <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>
1374 <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>
1375 <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>
1376 <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>
1377 <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>
1378 <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>
1379 <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>
1380 <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>
1381 <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>
1382 <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>
1383 <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>
1384 <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>
1385 <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>
1386 <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>
1387 <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>
1388 <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>
1389 <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>
1390 <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>
1391 </pre></div>
1392 </div>
1393 </section>
1394 </section>
1395 </section>
1396 <section id="part-v-functions-that-use-the-stack">
1397 <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>
1398 <p>Consider the <code class="docutils literal notranslate"><span class="pre">stack</span></code> function which grabs the whole stack, quotes it,
1399 and puts it on itself:</p>
1400 <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>
1401 <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>
1402 <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>
1403 </pre></div>
1404 </div>
1405 <p>We would like to represent this in Python somehow. To do this we use a
1406 simple, elegant trick.</p>
1407 <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>
1408 <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>
1409 <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>
1410 </pre></div>
1411 </div>
1412 <p>Instead of representing the stack effect comments as a single tuple
1413 (with N items in it) we use the same cons-list structure to hold the
1414 sequence and <code class="docutils literal notranslate"><span class="pre">unify()</span></code> the whole comments.</p>
1415 <section id="stackuncons">
1416 <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>
1417 <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>
1418 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>stack∘uncons (... a -- ... a a [...])
1419 </pre></div>
1420 </div>
1421 <p>The stack effects are:</p>
1422 <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
1424 <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>
1425 </pre></div>
1426 </div>
1427 <p>Unifying:</p>
1428 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>  S    -- (S, S) ∘ ((a, Z), S) -- (Z, (a,   S   ))
1429                                                     w/ { S: (a, Z) }
1430 (a, Z) --        ∘             -- (Z, (a, (a, Z)))
1431 </pre></div>
1432 </div>
1433 <p>So:</p>
1434 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>stack∘uncons == (a, Z) -- (Z, (a, (a, Z)))
1435 </pre></div>
1436 </div>
1437 <p>It works.</p>
1438 </section>
1439 <section id="stackunconsuncons">
1440 <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>
1441 <p>Let’s try <code class="docutils literal notranslate"><span class="pre">stack∘uncons∘uncons</span></code>:</p>
1442 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(a, S     ) -- (S,      (a, (a, S     ))) ∘ ((b, Z),  S`             ) -- (Z, (b,   S`   ))
1443
1444                                                                                 w/ { S: (b, Z) }
1445
1446 (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z),  S`             ) -- (Z, (b,   S`   ))
1447
1448                                                                                 w/ { S`: (a, (a, (b, Z))) }
1449
1450 (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), (a, (a, (b, Z)))) -- (Z, (b, (a, (a, (b, Z)))))
1451
1452 (a, (b, Z)) -- (Z, (b, (a, (a, (b, Z)))))
1453 </pre></div>
1454 </div>
1455 <p>It works.</p>
1456 <section id="compose-version-2">
1457 <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>
1458 <p>This function has to be modified to use the new datastructures and it is
1459 no longer recursive, instead recursion happens as part of unification.
1460 Further, the first and second of Pöial’s rules are now handled
1461 automatically by the unification algorithm. (One easy way to see this is
1462 that now an empty stack effect comment is represented by a
1463 <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> instance which is not “falsey” and so neither of the
1464 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
1465 the “truthiness” of <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> to false to let e.g.
1466 <code class="docutils literal notranslate"><span class="pre">joy.utils.stack.concat</span></code> work with our stack effect comment cons-list
1467 tuples.)</p>
1468 <div class="highlight-ipython2 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>
1469     <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>
1470     <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>
1471     <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>
1472         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
1473     <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>
1474 </pre></div>
1475 </div>
1476 <p>I don’t want to rewrite all the defs myself, so I’ll write a little
1477 conversion function instead. This is programmer’s laziness.</p>
1478 <div class="highlight-ipython2 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>
1479     <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>
1480     <span class="k">return</span> <span class="n">stack</span>
1481
1482 <span class="n">NEW_DEFS</span> <span class="o">=</span> <span class="p">{</span>
1483     <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>
1484     <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>
1485 <span class="p">}</span>
1486 <span class="n">NEW_DEFS</span><span class="p">[</span><span class="s1">&#39;stack&#39;</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>
1487 <span class="n">NEW_DEFS</span><span class="p">[</span><span class="s1">&#39;swaack&#39;</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>
1488 <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>
1489 </pre></div>
1490 </div>
1491 <div class="highlight-ipython2 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>
1492 </pre></div>
1493 </div>
1494 <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>
1495 </pre></div>
1496 </div>
1497 <div class="highlight-ipython2 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>
1498 </pre></div>
1499 </div>
1500 <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>
1501 </pre></div>
1502 </div>
1503 <p>The display function should be changed too.</p>
1504 </section>
1505 </section>
1506 <section id="doc-from-stack-effect-version-2">
1507 <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>
1508 <p>Clunky junk, but it will suffice for now.</p>
1509 <div class="highlight-ipython2 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>
1510     <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 &#39;...&#39; for the rest of the main stack?</span>
1511     <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>
1512     <span class="k">if</span> <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
1513         <span class="n">i</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;...&#39;</span><span class="p">)</span>
1514         <span class="n">o</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;...&#39;</span><span class="p">)</span>
1515     <span class="k">return</span> <span class="s1">&#39;(</span><span class="si">%s</span><span class="s1">--</span><span class="si">%s</span><span class="s1">)&#39;</span> <span class="o">%</span> <span class="p">(</span>
1516         <span class="s1">&#39; &#39;</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">&#39;&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="n">i</span><span class="p">)),</span>
1517         <span class="s1">&#39; &#39;</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">&#39;&#39;</span><span class="p">])),</span>
1518     <span class="p">)</span>
1519
1520
1521 <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>
1522     <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
1523     <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>
1524         <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
1525         <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>
1526     <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>
1527     <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>
1528     <span class="k">return</span> <span class="n">a</span>
1529
1530
1531 <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>
1532     <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>
1533         <span class="k">if</span> <span class="n">term</span> <span class="o">==</span> <span class="n">stack</span><span class="p">:</span>
1534             <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>
1535             <span class="k">return</span> <span class="s1">&#39;[...]&#39;</span>
1536         <span class="k">return</span> <span class="p">(</span>
1537             <span class="s1">&#39;[.</span><span class="si">%i</span><span class="s1">.]&#39;</span> <span class="o">%</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
1538             <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>
1539             <span class="k">else</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
1540         <span class="p">)</span>
1541
1542     <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
1543     <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>
1544         <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
1545         <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>
1546     <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>
1547     <span class="k">if</span> <span class="n">term</span> <span class="o">==</span> <span class="n">stack</span><span class="p">:</span>
1548         <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>
1549         <span class="n">end</span> <span class="o">=</span> <span class="s1">&#39;...&#39;</span>
1550     <span class="k">else</span><span class="p">:</span>
1551         <span class="n">end</span> <span class="o">=</span> <span class="s1">&#39;.</span><span class="si">%i</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
1552     <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>
1553     <span class="k">return</span> <span class="s1">&#39;[</span><span class="si">%s</span><span class="s1">]&#39;</span> <span class="o">%</span> <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
1554 </pre></div>
1555 </div>
1556 <div class="highlight-ipython2 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>
1557     <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
1558 </pre></div>
1559 </div>
1560 <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>
1561 <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>
1562 <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>
1563 <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>
1564 <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>
1565 <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>
1566 <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>
1567 <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>
1568 <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>
1569 <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>
1570 <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>
1571 <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>
1572 <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>
1573 <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>
1574 <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>
1575 <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>
1576 <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>
1577 <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>
1578 <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>
1579 <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>
1580 <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>
1581 <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>
1582 <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>
1583 <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>
1584 <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>
1585 <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>
1586 <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>
1587 <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>
1588 </pre></div>
1589 </div>
1590 <div class="highlight-ipython2 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>
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">C</span><span class="p">(</span><span class="n">stack</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">uncons</span><span class="p">)))</span>
1593 <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>
1594 </pre></div>
1595 </div>
1596 <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
1598 <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
1600 <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
1602 <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>
1603 </pre></div>
1604 </div>
1605 <div class="highlight-ipython2 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>
1606 </pre></div>
1607 </div>
1608 <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>
1609 </pre></div>
1610 </div>
1611 <div class="highlight-ipython2 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
1613 <span class="n">Q</span>
1614 </pre></div>
1615 </div>
1616 <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>
1617 </pre></div>
1618 </div>
1619 <section id="compile-version-3">
1620 <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>
1621 <p>This makes the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function pretty simple as the stack effect
1622 comments are now already in the form needed for the Python code:</p>
1623 <div class="highlight-ipython2 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>
1624     <span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">f</span>
1625     <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1626         <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>
1627     <span class="k">return</span> <span class="s1">&#39;&#39;&#39;def </span><span class="si">%s</span><span class="s1">(stack):</span>
1628 <span class="s1">    &quot;&quot;&quot;</span><span class="si">%s</span><span class="s1">&quot;&quot;&quot;</span>
1629 <span class="s1">    </span><span class="si">%s</span><span class="s1"> = stack</span>
1630 <span class="s1">    return </span><span class="si">%s</span><span class="s1">&#39;&#39;&#39;</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>
1631 </pre></div>
1632 </div>
1633 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;Q&#39;</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span>
1634 </pre></div>
1635 </div>
1636 <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>
1637     <span class="sd">&quot;&quot;&quot;(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])&quot;&quot;&quot;</span>
1638     <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>
1639     <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>
1640 </pre></div>
1641 </div>
1642 <div class="highlight-ipython2 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>
1643 <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>
1644 </pre></div>
1645 </div>
1646 <div class="highlight-ipython2 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>
1647 </pre></div>
1648 </div>
1649 <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>
1650 </pre></div>
1651 </div>
1652 <div class="highlight-ipython2 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>
1653 </pre></div>
1654 </div>
1655 <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>
1656 </pre></div>
1657 </div>
1658 <div class="highlight-ipython2 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>
1659 </pre></div>
1660 </div>
1661 <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>
1662 </pre></div>
1663 </div>
1664 <div class="highlight-ipython2 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>
1665 </pre></div>
1666 </div>
1667 <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>
1668 </pre></div>
1669 </div>
1670 <div class="highlight-ipython2 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>
1671 </pre></div>
1672 </div>
1673 <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>
1674 </pre></div>
1675 </div>
1676 </section>
1677 </section>
1678 </section>
1679 <section id="part-vi-multiple-stack-effects">
1680 <h2>Part VI: Multiple Stack Effects<a class="headerlink" href="#part-vi-multiple-stack-effects" title="Permalink to this headline">¶</a></h2>
1681 <p>…</p>
1682 <div class="highlight-ipython2 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">&#39;i&#39;</span>
1683
1684
1685 <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>
1686 <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>
1687 </pre></div>
1688 </div>
1689 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">muls</span> <span class="o">=</span> <span class="p">[</span>
1690      <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>
1691      <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>
1692      <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>
1693      <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>
1694 <span class="p">]</span>
1695 </pre></div>
1696 </div>
1697 <div class="highlight-ipython2 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>
1698     <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>
1699 </pre></div>
1700 </div>
1701 <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>
1702 <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>
1703 <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>
1704 <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>
1705 </pre></div>
1706 </div>
1707 <div class="highlight-ipython2 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>
1708     <span class="k">try</span><span class="p">:</span>
1709         <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>
1710     <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
1711         <span class="k">continue</span>
1712     <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>
1713 </pre></div>
1714 </div>
1715 <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>
1716 <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>
1717 </pre></div>
1718 </div>
1719 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">product</span>
1720
1721
1722 <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>
1723     <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>
1724         <span class="k">try</span><span class="p">:</span>
1725             <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>
1726         <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
1727             <span class="k">pass</span>
1728
1729
1730 <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>
1731     <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>
1732 </pre></div>
1733 </div>
1734 <div class="highlight-ipython2 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>
1735     <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>
1736 </pre></div>
1737 </div>
1738 <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>
1739 </pre></div>
1740 </div>
1741 <div class="highlight-ipython2 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>
1742     <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>
1743 </pre></div>
1744 </div>
1745 <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>
1746 <span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
1747 </pre></div>
1748 </div>
1749 <section id="representing-an-unbounded-sequence-of-types">
1750 <h3>Representing an Unbounded Sequence of Types<a class="headerlink" href="#representing-an-unbounded-sequence-of-types" title="Permalink to this headline">¶</a></h3>
1751 <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 Expressions</a> to
1753 invent a new type of type variable, a “sequence type” (I think this is
1754 what they mean in the literature by that term…) or “<a class="reference external" href="https://en.wikipedia.org/wiki/Kleene_star">Kleene
1755 Star</a>” type. I’m going to
1756 represent it as a type letter and the asterix, so a sequence of zero or
1757 more <code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> variables would be:</p>
1758 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span><span class="o">*</span>
1759 </pre></div>
1760 </div>
1761 <p>The <code class="docutils literal notranslate"><span class="pre">A*</span></code> works by splitting the universe into two alternate histories:</p>
1762 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span><span class="o">*</span> <span class="o">-&gt;</span> <span class="mi">0</span> <span class="o">|</span> <span class="n">A</span> <span class="n">A</span><span class="o">*</span>
1763 </pre></div>
1764 </div>
1765 <p>The Kleene star variable disappears in one universe, and in the other it
1766 turns into an <code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> variable followed by itself again. We have
1767 to return all universes (represented by their substitution dicts, the
1768 “unifiers”) that don’t lead to type conflicts.</p>
1769 <p>Consider unifying two stacks (the lowercase letters are any type
1770 variables of the kinds we have defined so far):</p>
1771 <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>
1772                           <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>
1773 <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>
1774 </pre></div>
1775 </div>
1776 <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 disappears:</p>
1778 <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>
1779                    <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>
1780      <span class="p">[]</span> <span class="n">U</span> <span class="p">[]</span>
1781 </pre></div>
1782 </div>
1783 <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>
1784 <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>
1785                         <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>
1786 <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>
1787                         <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>
1788 <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>
1789 </pre></div>
1790 </div>
1791 <p>Giving us two unifiers:</p>
1792 <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>
1793 <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>
1794 </pre></div>
1795 </div>
1796 <div class="highlight-ipython2 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
1798     <span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
1799
1800     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
1801         <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
1802         <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
1803         <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
1805     <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1806         <span class="k">return</span> <span class="s1">&#39;</span><span class="si">%s%i</span><span class="s1">*&#39;</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
1808     <span class="k">def</span> <span class="nf">another</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1809         <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
1810         <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
1812     <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
1813         <span class="k">return</span> <span class="p">(</span>
1814             <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>
1815             <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>
1816         <span class="p">)</span>
1817
1818     <span class="k">def</span> <span class="fm">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
1819         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span> <span class="o">&gt;=</span> <span class="n">other</span><span class="o">.</span><span class="n">kind</span>
1820
1821     <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
1822         <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>
1823     <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
1824
1825     <span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1826         <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
1828 <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>
1829 <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>
1830 <span class="c1">#class FloatStarJoyType(KleeneStar): kind = FloatJoyType</span>
1831 <span class="c1">#class IntStarJoyType(KleeneStar): kind = IntJoyType</span>
1832 <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>
1833
1834
1835 <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>
1836 <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>
1837 <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>
1838 </pre></div>
1839 </div>
1840 <section id="unify-version-4">
1841 <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>
1842 <p>Can now return multiple results…</p>
1843 <div class="highlight-ipython2 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>
1844     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1845         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
1846     <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
1847         <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>
1848         <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
1850     <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
1851         <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1852
1853     <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>
1854         <span class="k">if</span> <span class="n">u</span> <span class="o">&gt;=</span> <span class="n">v</span><span class="p">:</span>
1855             <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>
1856             <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1857         <span class="k">if</span> <span class="n">v</span> <span class="o">&gt;=</span> <span class="n">u</span><span class="p">:</span>
1858             <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>
1859             <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1860         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
1861
1862     <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>
1863         <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>
1864             <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
1866         <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">v</span>
1867         <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>
1868             <span class="c1"># Two universes, in one the Kleene star disappears and unification</span>
1869             <span class="c1"># continues without it...</span>
1870             <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
1872             <span class="c1"># In the other it spawns a new variable.</span>
1873             <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
1875             <span class="n">t</span> <span class="o">=</span> <span class="n">s0</span> <span class="o">+</span> <span class="n">s1</span>
1876             <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">t</span><span class="p">:</span>
1877                 <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>
1878             <span class="k">return</span> <span class="n">t</span>
1879
1880         <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">u</span>
1881         <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>
1882             <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>
1883             <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>
1884             <span class="n">t</span> <span class="o">=</span> <span class="n">s0</span> <span class="o">+</span> <span class="n">s1</span>
1885             <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">t</span><span class="p">:</span>
1886                 <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>
1887             <span class="k">return</span> <span class="n">t</span>
1888
1889         <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>
1890         <span class="n">results</span> <span class="o">=</span> <span class="p">()</span>
1891         <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">ses</span><span class="p">:</span>
1892             <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>
1893         <span class="k">return</span> <span class="n">results</span>
1894
1895     <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>
1896         <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>
1897             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">))</span>
1898         <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>
1899         <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1900
1901     <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>
1902         <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>
1903             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">u</span><span class="p">))</span>
1904         <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>
1905         <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1906
1907     <span class="k">return</span> <span class="p">()</span>
1908
1909
1910 <span class="k">def</span> <span class="nf">stacky</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
1911     <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>
1912 </pre></div>
1913 </div>
1914 <div class="highlight-ipython2 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>
1915 <span class="n">a</span>
1916 </pre></div>
1917 </div>
1918 <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>
1919 </pre></div>
1920 </div>
1921 <div class="highlight-ipython2 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>
1922 <span class="n">b</span>
1923 </pre></div>
1924 </div>
1925 <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>
1926 </pre></div>
1927 </div>
1928 <div class="highlight-ipython2 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>
1929     <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</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>
1930 </pre></div>
1931 </div>
1932 <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">-&gt;</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>
1933 <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">-&gt;</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>
1934 </pre></div>
1935 </div>
1936 <div class="highlight-ipython2 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>
1937     <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</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>
1938 </pre></div>
1939 </div>
1940 <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">-&gt;</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>
1941 <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">-&gt;</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>
1942 </pre></div>
1943 </div>
1944 <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
1946 <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
1948 <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>
1949 </pre></div>
1950 </div>
1951 <div class="highlight-ipython2 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
1953 <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>
1954 </pre></div>
1955 </div>
1956 <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>
1957 </pre></div>
1958 </div>
1959 <div class="highlight-ipython2 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
1961 <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>
1962 </pre></div>
1963 </div>
1964 <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>
1965 </pre></div>
1966 </div>
1967 <div class="highlight-ipython2 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>
1968     <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">&#39;-&gt;&#39;</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>
1969 </pre></div>
1970 </div>
1971 <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">-&gt;</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">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">-&gt;</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">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">-&gt;</span> <span class="p">(</span><span class="n">n0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)</span>
1974 <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">-&gt;</span> <span class="p">(</span><span class="n">n0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)</span>
1975 </pre></div>
1976 </div>
1977 </section>
1978 <section id="compose-version-3">
1979 <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>
1980 <p>This function has to be modified to yield multiple results.</p>
1981 <div class="highlight-ipython2 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>
1982     <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>
1983     <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>
1984     <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
1985         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;Cannot unify </span><span class="si">%r</span><span class="s1"> and </span><span class="si">%r</span><span class="s1">.&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">f_out</span><span class="p">,</span> <span class="n">g_in</span><span class="p">))</span>
1986     <span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
1987         <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>
1988 </pre></div>
1989 </div>
1990 <div class="highlight-ipython2 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>
1991     <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>
1992         <span class="k">try</span><span class="p">:</span>
1993             <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>
1994                 <span class="k">yield</span> <span class="n">result</span>
1995         <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
1996             <span class="k">pass</span>
1997
1998
1999 <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>
2000     <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>
2001     <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>
2002         <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
2003 </pre></div>
2004 </div>
2005 <div class="highlight-ipython2 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>
2006     <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>
2007 </pre></div>
2008 </div>
2009 <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>
2010 <span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
2011 </pre></div>
2012 </div>
2013 <div class="highlight-ipython2 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>
2014     <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>
2015 </pre></div>
2016 </div>
2017 <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>
2018 </pre></div>
2019 </div>
2020 <div class="highlight-ipython2 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>
2021     <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>
2022 </pre></div>
2023 </div>
2024 <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>
2025 <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>
2026 </pre></div>
2027 </div>
2028 <div class="highlight-ipython2 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>
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">cons</span><span class="p">),</span>
2030 <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
2032 <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>
2033     <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>
2034 </pre></div>
2035 </div>
2036 <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>
2037 </pre></div>
2038 </div>
2039 <div class="highlight-ipython2 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>
2040 <span class="n">a</span>
2041 </pre></div>
2042 </div>
2043 <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>
2044 </pre></div>
2045 </div>
2046 <div class="highlight-ipython2 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>
2047 <span class="n">b</span>
2048 </pre></div>
2049 </div>
2050 <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>
2051 </pre></div>
2052 </div>
2053 <div class="highlight-ipython2 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>
2054     <span class="nb">print</span> <span class="n">result</span>
2055 </pre></div>
2056 </div>
2057 <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>
2058 <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>
2059 </pre></div>
2060 </div>
2061 <div class="highlight-ipython2 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>
2062     <span class="nb">print</span> <span class="n">result</span>
2063 </pre></div>
2064 </div>
2065 <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>
2066 <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>
2067 </pre></div>
2068 </div>
2069 </section>
2070 </section>
2071 </section>
2072 <section id="part-vii-typing-combinators">
2073 <h2>Part VII: Typing Combinators<a class="headerlink" href="#part-vii-typing-combinators" title="Permalink to this headline">¶</a></h2>
2074 <p>In order to compute the stack effect of combinators you kinda have to
2075 have the quoted programs they expect available. In the most general
2076 case, the <code class="docutils literal notranslate"><span class="pre">i</span></code> combinator, you can’t say anything about its stack
2077 effect other than it expects one quote:</p>
2078 <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>
2079 </pre></div>
2080 </div>
2081 <p>Or</p>
2082 <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>
2083 </pre></div>
2084 </div>
2085 <p>Consider the type of:</p>
2086 <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>
2087 </pre></div>
2088 </div>
2089 <p>Obviously it would be:</p>
2090 <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>
2091 </pre></div>
2092 </div>
2093 <p><code class="docutils literal notranslate"><span class="pre">dip</span></code> itself could have:</p>
2094 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(a1 [..1] -- ... then what?
2095 </pre></div>
2096 </div>
2097 <p>Without any information about the contents of the quote we can’t say
2098 much about the result.</p>
2099 <section id="hybrid-inferencer-interpreter">
2100 <h3>Hybrid Inferencer/Interpreter<a class="headerlink" href="#hybrid-inferencer-interpreter" title="Permalink to this headline">¶</a></h3>
2101 <p>I think there’s a way forward. If we convert our list (of terms we are
2102 composing) into a stack structure we can use it as a <em>Joy expression</em>,
2103 then we can treat the <em>output half</em> of a function’s stack effect comment
2104 as a Joy interpreter stack, and just execute combinators directly. We
2105 can hybridize the compostition function with an interpreter to evaluate
2106 combinators, compose non-combinator functions, and put type variables on
2107 the stack. For combinators like <code class="docutils literal notranslate"><span class="pre">branch</span></code> that can have more than one
2108 stack effect we have to “split universes” again and return both.</p>
2109 <section id="joy-types-for-functions">
2110 <h4>Joy Types for Functions<a class="headerlink" href="#joy-types-for-functions" title="Permalink to this headline">¶</a></h4>
2111 <p>We need a type variable for Joy functions that can go in our expressions
2112 and be used by the hybrid inferencer/interpreter. They have to store a
2113 name and a list of stack effects.</p>
2114 <div class="highlight-ipython2 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
2116     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
2117         <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
2118         <span class="bp">self</span><span class="o">.</span><span class="n">stack_effects</span> <span class="o">=</span> <span class="n">sec</span>
2119         <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
2120
2121     <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
2122         <span class="k">return</span> <span class="bp">self</span>
2123     <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
2124
2125     <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
2126         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
2127 </pre></div>
2128 </div>
2129 </section>
2130 <section id="specialized-for-simple-functions-and-combinators">
2131 <h4>Specialized for Simple Functions and Combinators<a class="headerlink" href="#specialized-for-simple-functions-and-combinators" title="Permalink to this headline">¶</a></h4>
2132 <p>For non-combinator functions the stack effects list contains stack
2133 effect comments (represented by pairs of cons-lists as described above.)</p>
2134 <div class="highlight-ipython2 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>
2135     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;F&#39;</span>
2136 </pre></div>
2137 </div>
2138 <p>For combinators the list contains Python functions.</p>
2139 <div class="highlight-ipython2 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
2141     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;C&#39;</span>
2142
2143     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">,</span> <span class="n">expect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
2144         <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>
2145         <span class="bp">self</span><span class="o">.</span><span class="n">expect</span> <span class="o">=</span> <span class="n">expect</span>
2146
2147     <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>
2148         <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>
2149             <span class="k">return</span> <span class="n">f</span>
2150         <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>
2151         <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>
2152         <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>
2153         <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>
2154 </pre></div>
2155 </div>
2156 <p>For simple combinators that have only one effect (like <code class="docutils literal notranslate"><span class="pre">dip</span></code>) you only
2157 need one function and it can be the combinator itself.</p>
2158 <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">joy.library</span>
2159
2160 <span class="n">dip</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">&#39;dip&#39;</span><span class="p">,</span> <span class="p">[</span><span class="n">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>
2161 </pre></div>
2162 </div>
2163 <p>For combinators that can have more than one effect (like <code class="docutils literal notranslate"><span class="pre">branch</span></code>) you
2164 have to write functions that each implement the action of one of the
2165 effects.</p>
2166 <div class="highlight-ipython2 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>
2167     <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>
2168     <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
2170 <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>
2171     <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>
2172     <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
2174 <span class="n">branch</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">&#39;branch&#39;</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>
2175 </pre></div>
2176 </div>
2177 <p>You can also provide an optional stack effect, input-side only, that
2178 will then be used as an identity function (that accepts and returns
2179 stacks that match the “guard” stack effect) which will be used to guard
2180 against type mismatches going into the evaluation of the combinator.</p>
2181 </section>
2182 <section id="infer">
2183 <h4><code class="docutils literal notranslate"><span class="pre">infer()</span></code><a class="headerlink" href="#infer" title="Permalink to this headline">¶</a></h4>
2184 <p>With those in place, we can define a function that accepts a sequence of
2185 Joy type variables, including ones representing functions (not just
2186 values), and attempts to grind out all the possible stack effects of
2187 that expression.</p>
2188 <p>One tricky thing is that type variables <em>in the expression</em> have to be
2189 updated along with the stack effects after doing unification or we risk
2190 losing useful information. This was a straightforward, if awkward,
2191 modification to the call structure of <code class="docutils literal notranslate"><span class="pre">meta_compose()</span></code> et. al.</p>
2192 <div class="highlight-ipython2 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>
2193
2194
2195 <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>
2196     <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>
2197
2198
2199 <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>
2200     <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>
2201     <span class="k">if</span> <span class="ow">not</span> <span class="n">e</span><span class="p">:</span>
2202         <span class="k">return</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span>
2203
2204     <span class="n">n</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">e</span>
2205
2206     <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>
2207         <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>
2208         <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
2210     <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>
2211         <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>
2212         <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
2214     <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>
2215         <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>
2216         <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>
2217         <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
2219     <span class="k">else</span><span class="p">:</span>
2220         <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">F</span>
2221         <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
2223     <span class="k">return</span> <span class="n">res</span>
2224
2225
2226 <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>
2227     <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>
2228     <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>
2229     <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>
2230     <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>
2231
2232
2233 <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>
2234     <span class="n">_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
2235         <span class="sa">u</span><span class="s1">&#39;</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">&#39;</span><span class="p">,</span>
2236         <span class="nb">len</span><span class="p">(</span><span class="n">inspect_stack</span><span class="p">()),</span>
2237         <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>
2238         <span class="n">expression_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
2239         <span class="p">)</span>
2240 </pre></div>
2241 </div>
2242 </section>
2243 <section id="work-in-progress">
2244 <h4>Work in Progress<a class="headerlink" href="#work-in-progress" title="Permalink to this headline">¶</a></h4>
2245 <p>And that brings us to current Work-In-Progress. The mixed-mode
2246 inferencer/interpreter <code class="docutils literal notranslate"><span class="pre">infer()</span></code> function seems to work well. There
2247 are details I should document, and the rest of the code in the <code class="docutils literal notranslate"><span class="pre">types</span></code>
2248 module (FIXME link to its docs here!) should be explained… There is
2249 cruft to convert the definitions in <code class="docutils literal notranslate"><span class="pre">DEFS</span></code> to the new
2250 <code class="docutils literal notranslate"><span class="pre">SymbolJoyType</span></code> objects, and some combinators. Here is an example of
2251 output from the current code :</p>
2252 <div class="highlight-ipython2 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&#39;t try to run this cell!  It&#39;s not going to work.  This is &quot;read only&quot; code heh..)</span>
2253
2254 <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">&#39;</span><span class="si">%(message)s</span><span class="s1">&#39;</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
2256 <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
2258 <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
2260 <span class="nb">print</span> <span class="s1">&#39;-&#39;</span> <span class="o">*</span> <span class="mi">40</span>
2261
2262 <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>
2263     <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>
2264 </pre></div>
2265 </div>
2266 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">---------------------------------------------------------------------------</span>
2267
2268 <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
2270 <span class="o">&lt;</span><span class="n">ipython</span><span class="o">-</span><span class="nb">input</span><span class="o">-</span><span class="mi">1</span><span class="o">-</span><span class="mi">9</span><span class="n">a9d60354c35</span><span class="o">&gt;</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span><span class="p">()</span>
2271 <span class="o">----&gt;</span> <span class="mi">1</span> <span class="mi">1</span><span class="o">/</span><span class="mi">0</span>  <span class="c1"># (Don&#39;t try to run this cell!  It&#39;s not going to work.  This is &quot;read only&quot; code heh..)</span>
2272       <span class="mi">2</span>
2273       <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">&#39;</span><span class="si">%(message)s</span><span class="s1">&#39;</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>
2274       <span class="mi">4</span>
2275       <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>
2276
2277
2278 <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>
2279 </pre></div>
2280 </div>
2281 <p>The numbers at the start of the lines are the current depth of the
2282 Python call stack. They’re followed by the current computed stack effect
2283 (initialized to <code class="docutils literal notranslate"><span class="pre">ID</span></code>) then the pending expression (the inference of
2284 the stack effect of which is the whole object of the current example.)</p>
2285 <p>In this example we are implementing (and inferring) <code class="docutils literal notranslate"><span class="pre">ifte</span></code> as
2286 <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
2287 implementation in action.</p>
2288 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>  7 (--) ∘ [pred] [mul] [div] [nullary bool] dipd branch
2289   8 (-- [pred ...2]) ∘ [mul] [div] [nullary bool] dipd branch
2290   9 (-- [pred ...2] [mul ...3]) ∘ [div] [nullary bool] dipd branch
2291  10 (-- [pred ...2] [mul ...3] [div ...4]) ∘ [nullary bool] dipd branch
2292  11 (-- [pred ...2] [mul ...3] [div ...4] [nullary bool ...5]) ∘ dipd branch
2293  15 (-- [pred ...5]) ∘ nullary bool [mul] [div] branch
2294  19 (-- [pred ...2]) ∘ [stack] dinfrirst bool [mul] [div] branch
2295  20 (-- [pred ...2] [stack ]) ∘ dinfrirst bool [mul] [div] branch
2296  22 (-- [pred ...2] [stack ]) ∘ dip infra first bool [mul] [div] branch
2297  26 (--) ∘ stack [pred] infra first bool [mul] [div] branch
2298  29 (... -- ... [...]) ∘ [pred] infra first bool [mul] [div] branch
2299  30 (... -- ... [...] [pred ...1]) ∘ infra first bool [mul] [div] branch
2300  34 (--) ∘ pred s1 swaack first bool [mul] [div] branch
2301  37 (n1 -- n2) ∘ [n1] swaack first bool [mul] [div] branch
2302  38 (... n1 -- ... n2 [n1 ...]) ∘ swaack first bool [mul] [div] branch
2303  41 (... n1 -- ... n1 [n2 ...]) ∘ first bool [mul] [div] branch
2304  44 (n1 -- n1 n2) ∘ bool [mul] [div] branch
2305  47 (n1 -- n1 b1) ∘ [mul] [div] branch
2306  48 (n1 -- n1 b1 [mul ...1]) ∘ [div] branch
2307  49 (n1 -- n1 b1 [mul ...1] [div ...2]) ∘ branch
2308  53 (n1 -- n1) ∘ div
2309  56 (f2 f1 -- f3) ∘
2310  56 (i1 f1 -- f2) ∘
2311  56 (f1 i1 -- f2) ∘
2312  56 (i2 i1 -- f1) ∘
2313  53 (n1 -- n1) ∘ mul
2314  56 (f2 f1 -- f3) ∘
2315  56 (i1 f1 -- f2) ∘
2316  56 (f1 i1 -- f2) ∘
2317  56 (i2 i1 -- i3) ∘
2318 ----------------------------------------
2319 (f2 f1 -- f3)
2320 (i1 f1 -- f2)
2321 (f1 i1 -- f2)
2322 (i2 i1 -- f1)
2323 (i2 i1 -- i3)
2324 </pre></div>
2325 </div>
2326 </section>
2327 </section>
2328 </section>
2329 <section id="conclusion">
2330 <h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this headline">¶</a></h2>
2331 <p>We built a simple type inferencer, and a kind of crude “compiler” for a
2332 subset of Joy functions. Then we built a more powerful inferencer that
2333 actually does some evaluation and explores branching code paths</p>
2334 <p>Work remains to be done:</p>
2335 <ul class="simple">
2336 <li><p>the rest of the library has to be covered</p></li>
2337 <li><p>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..</p></li>
2338 <li><p>extend the types to check values (see the appendix)</p></li>
2339 <li><p>other kinds of “higher order” type variables, OR, AND, etc..</p></li>
2340 <li><p>maybe rewrite in Prolog for great good?</p></li>
2341 <li><p>definitions</p>
2342 <ul>
2343 <li><p>don’t permit composition of functions that don’t compose</p></li>
2344 <li><p>auto-compile compilable functions</p></li>
2345 </ul>
2346 </li>
2347 <li><p>Compiling more than just the Yin functions.</p></li>
2348 <li><p>getting better visibility (than Python debugger.)</p></li>
2349 <li><p>DOOOOCS!!!! Lots of docs!</p>
2350 <ul>
2351 <li><p>docstrings all around</p></li>
2352 <li><p>improve this notebook (it kinda falls apart at the end
2353 narratively. I went off and just started writing code to see if it
2354 would work. It does, but now I have to come back and describe here
2355 what I did.</p></li>
2356 </ul>
2357 </li>
2358 </ul>
2359 </section>
2360 <section id="appendix-joy-in-the-logical-paradigm">
2361 <h2>Appendix: Joy in the Logical Paradigm<a class="headerlink" href="#appendix-joy-in-the-logical-paradigm" title="Permalink to this headline">¶</a></h2>
2362 <p>For <em>type checking</em> to work the type label classes have to be modified
2363 to let <code class="docutils literal notranslate"><span class="pre">T</span> <span class="pre">&gt;=</span> <span class="pre">t</span></code> succeed, where e.g. <code class="docutils literal notranslate"><span class="pre">T</span></code> is <code class="docutils literal notranslate"><span class="pre">IntJoyType</span></code> and <code class="docutils literal notranslate"><span class="pre">t</span></code>
2364 is <code class="docutils literal notranslate"><span class="pre">int</span></code>. If you do that you can take advantage of the <em>logical
2365 relational</em> nature of the stack effect comments to “compute in reverse”
2366 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>
2367 module. But if you’re interested in all that you should just use Prolog!</p>
2368 <p>Anyhow, type <em>checking</em> is a few easy steps away.</p>
2369 <div class="highlight-ipython2 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>
2370     <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>
2371             <span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">&#39;accept&#39;</span><span class="p">)</span>
2372             <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>
2373
2374 <span class="n">AnyJoyType</span><span class="o">.</span><span class="fm">__ge__</span> <span class="o">=</span> <span class="n">_ge</span>
2375 <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>
2376 <span class="n">StackJoyType</span><span class="o">.</span><span class="n">accept</span> <span class="o">=</span> <span class="nb">tuple</span>
2377 </pre></div>
2378 </div>
2379 </section>
2380 </section>
2381
2382
2383           </div>
2384           
2385         </div>
2386       </div>
2387       <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
2388         <div class="sphinxsidebarwrapper">
2389 <h1 class="logo"><a href="../index.html">Thun</a></h1>
2390
2391
2392
2393
2394
2395
2396
2397
2398 <h3>Navigation</h3>
2399 <ul class="current">
2400 <li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
2401 <li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
2402 <li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
2403 <li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
2404 <li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
2405 <li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
2406 <li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
2407 <li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
2408 <li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
2409 <li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
2410 <li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
2411 <li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
2412 <li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
2413 <li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
2414 <li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
2415 <li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
2416 <li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
2417 <li class="toctree-l2"><a class="reference internal" href="Square_Spiral.html">Square Spiral Example Joy Code</a></li>
2418 <li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
2419 <li class="toctree-l2 current"><a class="current reference internal" href="#">The Blissful Elegance of Typing Joy</a></li>
2420 <li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
2421 <li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
2422 <li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
2423 <li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
2424 <li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
2425 </ul>
2426 </li>
2427 </ul>
2428
2429 <div class="relations">
2430 <h3>Related Topics</h3>
2431 <ul>
2432   <li><a href="../index.html">Documentation overview</a><ul>
2433   <li><a href="index.html">Essays about Programming in Joy</a><ul>
2434       <li>Previous: <a href="Zipper.html" title="previous chapter">Traversing Datastructures with Zippers</a></li>
2435       <li>Next: <a href="TypeChecking.html" title="next chapter">Type Checking</a></li>
2436   </ul></li>
2437   </ul></li>
2438 </ul>
2439 </div>
2440 <div id="searchbox" style="display: none" role="search">
2441   <h3 id="searchlabel">Quick search</h3>
2442     <div class="searchformwrapper">
2443     <form class="search" action="../search.html" method="get">
2444       <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
2445       <input type="submit" value="Go" />
2446     </form>
2447     </div>
2448 </div>
2449 <script>$('#searchbox').show(0);</script>
2450
2451
2452
2453
2454
2455
2456
2457
2458         </div>
2459       </div>
2460       <div class="clearer"></div>
2461     </div>
2462     <div class="footer" role="contentinfo">
2463 <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
2464 <img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
2465 </a>
2466 <br />
2467 <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>.
2468       Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
2469     </div>
2470
2471   </body>
2472 </html>