OSDN Git Service

Update docs.
[joypy/Thun.git] / docs / sphinx_docs / _build / html / notebooks / Types.html
1
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
3   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5 <html xmlns="http://www.w3.org/1999/xhtml">
6   <head>
7     <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
8     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
9     <title>The Blissful Elegance of Typing Joy &#8212; Thun 0.2.0 documentation</title>
10     <link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
11     <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
12     <script type="text/javascript" src="../_static/documentation_options.js"></script>
13     <script type="text/javascript" src="../_static/jquery.js"></script>
14     <script type="text/javascript" src="../_static/underscore.js"></script>
15     <script type="text/javascript" src="../_static/doctools.js"></script>
16     <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
17     <link rel="index" title="Index" href="../genindex.html" />
18     <link rel="search" title="Search" href="../search.html" />
19     <link rel="next" title="Type Checking" href="TypeChecking.html" />
20     <link rel="prev" title="Traversing Datastructures with Zippers" href="Zipper.html" />
21    
22   <link rel="stylesheet" href="../_static/custom.css" type="text/css" />
23   
24   
25   <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
26
27   </head><body>
28   
29
30     <div class="document">
31       <div class="documentwrapper">
32         <div class="bodywrapper">
33           <div class="body" role="main">
34             
35   <div class="section" id="the-blissful-elegance-of-typing-joy">
36 <h1>The Blissful Elegance of Typing Joy<a class="headerlink" href="#the-blissful-elegance-of-typing-joy" title="Permalink to this headline">¶</a></h1>
37 <p>This notebook presents a simple type inferencer for Joy code. It can
38 infer the stack effect of most Joy expressions. It’s built largely by
39 means of existing ideas and research. (A great overview of the existing
40 knowledge is a talk <a class="reference external" href="http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/">“Type Inference in Stack-Based Programming
41 Languages”</a>
42 given by Rob Kleffner on or about 2017-03-10 as part of a course on the
43 history of programming languages.)</p>
44 <p>The notebook starts with a simple inferencer based on the work of Jaanus
45 Pöial which we then progressively elaborate to cover more Joy semantics.
46 Along the way we write a simple “compiler” that emits Python code for
47 what I like to call Yin functions. (Yin functions are those that only
48 rearrange values in stacks, as opposed to Yang functions that actually
49 work on the values themselves.)</p>
50 <div class="section" id="part-i-poial-s-rules">
51 <h2>Part I: Pöial’s Rules<a class="headerlink" href="#part-i-poial-s-rules" title="Permalink to this headline">¶</a></h2>
52 <p><a class="reference external" href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.212.6026">“Typing Tools for Typeless Stack Languages” by Jaanus
53 Pöial</a></p>
54 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@INPROCEEDINGS</span><span class="p">{</span><span class="n">Pöial06typingtools</span><span class="p">,</span>
55     <span class="n">author</span> <span class="o">=</span> <span class="p">{</span><span class="n">Jaanus</span> <span class="n">Pöial</span><span class="p">},</span>
56     <span class="n">title</span> <span class="o">=</span> <span class="p">{</span><span class="n">Typing</span> <span class="n">tools</span> <span class="k">for</span> <span class="n">typeless</span> <span class="n">stack</span> <span class="n">languages</span><span class="p">},</span>
57     <span class="n">booktitle</span> <span class="o">=</span> <span class="p">{</span><span class="n">In</span> <span class="mi">23</span><span class="n">rd</span> <span class="n">Euro</span><span class="o">-</span><span class="n">Forth</span> <span class="n">Conference</span><span class="p">},</span>
58     <span class="n">year</span> <span class="o">=</span> <span class="p">{</span><span class="mi">2006</span><span class="p">},</span>
59     <span class="n">pages</span> <span class="o">=</span> <span class="p">{</span><span class="mi">40</span><span class="o">--</span><span class="mi">46</span><span class="p">}</span>
60 <span class="p">}</span>
61 </pre></div>
62 </div>
63 <div class="section" id="first-rule">
64 <h3>First Rule<a class="headerlink" href="#first-rule" title="Permalink to this headline">¶</a></h3>
65 <p>This rule deals with functions (and literals) that put items on the
66 stack <code class="docutils literal notranslate"><span class="pre">(--</span> <span class="pre">d)</span></code>:</p>
67 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (a -- b)∘(-- d)
68 ---------------------
69      (a -- b d)
70 </pre></div>
71 </div>
72 </div>
73 <div class="section" id="second-rule">
74 <h3>Second Rule<a class="headerlink" href="#second-rule" title="Permalink to this headline">¶</a></h3>
75 <p>This rule deals with functions that consume items from the stack
76 <code class="docutils literal notranslate"><span class="pre">(a</span> <span class="pre">--)</span></code>:</p>
77 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (a --)∘(c -- d)
78 ---------------------
79      (c a -- d)
80 </pre></div>
81 </div>
82 </div>
83 <div class="section" id="third-rule">
84 <h3>Third Rule<a class="headerlink" href="#third-rule" title="Permalink to this headline">¶</a></h3>
85 <p>The third rule is actually two rules. These two rules deal with
86 composing functions when the second one will consume one of items the
87 first one produces. The two types must be
88 <a class="reference external" href="https://en.wikipedia.org/wiki/Robinson's_unification_algorithm">*unified*</a>
89 or a type conflict declared.</p>
90 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (a -- b t[i])∘(c u[j] -- d)   t &lt;= u (t is subtype of u)
91 -------------------------------
92    (a -- b     )∘(c      -- d)   t[i] == t[k] == u[j]
93                                          ^
94
95    (a -- b t[i])∘(c u[j] -- d)   u &lt;= t (u is subtype of t)
96 -------------------------------
97    (a -- b     )∘(c      -- d)   t[i] == u[k] == u[j]
98 </pre></div>
99 </div>
100 <p>Let’s work through some examples by hand to develop an intuition for the
101 algorithm.</p>
102 <p>There’s a function in one of the other notebooks.</p>
103 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">==</span> <span class="n">pop</span> <span class="n">swap</span> <span class="n">roll</span><span class="o">&lt;</span> <span class="n">rest</span> <span class="n">rest</span> <span class="n">cons</span> <span class="n">cons</span>
104 </pre></div>
105 </div>
106 <p>It’s all “stack chatter” and list manipulation so we should be able to
107 deduce its type.</p>
108 </div>
109 <div class="section" id="stack-effect-comments">
110 <h3>Stack Effect Comments<a class="headerlink" href="#stack-effect-comments" title="Permalink to this headline">¶</a></h3>
111 <p>Joy function types will be represented by Forth-style stack effect
112 comments. I’m going to use numbers instead of names to keep track of the
113 stack arguments. (A little bit like <a class="reference external" href="https://en.wikipedia.org/wiki/De_Bruijn_index">De Bruijn
114 index</a>, at least it
115 reminds me of them):</p>
116 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pop</span> <span class="p">(</span><span class="mi">1</span> <span class="o">--</span><span class="p">)</span>
117
118 <span class="n">swap</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
119
120 <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>
121 </pre></div>
122 </div>
123 <p>These commands alter the stack but don’t “look at” the values so these
124 numbers represent an “Any type”.</p>
125 </div>
126 <div class="section" id="pop-swap">
127 <h3><code class="docutils literal notranslate"><span class="pre">pop</span> <span class="pre">swap</span></code><a class="headerlink" href="#pop-swap" title="Permalink to this headline">¶</a></h3>
128 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="o">--</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
129 </pre></div>
130 </div>
131 <p>Here we encounter a complication. The argument numbers need to be made
132 unique among both sides. For this let’s change <code class="docutils literal notranslate"><span class="pre">pop</span></code> to use 0:</p>
133 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">0</span> <span class="o">--</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
134 </pre></div>
135 </div>
136 <p>Following the second rule:</p>
137 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
138 </pre></div>
139 </div>
140 </div>
141 <div class="section" id="popswap-roll">
142 <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>
143 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="o">--</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span><span class="p">)</span>
144 </pre></div>
145 </div>
146 <p>Let’s re-label them:</p>
147 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="n">a</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">1</span><span class="n">a</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
148 </pre></div>
149 </div>
150 <p>Now we follow the rules.</p>
151 <p>We must unify <code class="docutils literal notranslate"><span class="pre">1a</span></code> and <code class="docutils literal notranslate"><span class="pre">3b</span></code>, and <code class="docutils literal notranslate"><span class="pre">2a</span></code> and <code class="docutils literal notranslate"><span class="pre">2b</span></code>, replacing the
152 terms in the forms:</p>
153 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="n">a</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">1</span><span class="n">a</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
154                                             <span class="n">w</span><span class="o">/</span>  <span class="p">{</span><span class="mi">1</span><span class="n">a</span><span class="p">:</span> <span class="mi">3</span><span class="n">b</span><span class="p">}</span>
155 <span class="p">(</span><span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">a</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">a</span>   <span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span>    <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
156                                             <span class="n">w</span><span class="o">/</span>  <span class="p">{</span><span class="mi">2</span><span class="n">a</span><span class="p">:</span> <span class="mi">2</span><span class="n">b</span><span class="p">}</span>
157 <span class="p">(</span><span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span>      <span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span>       <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
158 </pre></div>
159 </div>
160 <p>Here we must apply the second rule:</p>
161 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   <span class="p">(</span><span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span><span class="p">)</span> <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
162 <span class="o">-----------------------------------</span>
163      <span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
164 </pre></div>
165 </div>
166 <p>Now we de-label the type, uh, labels:</p>
167 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">0</span><span class="n">a</span> <span class="o">--</span> <span class="mi">2</span><span class="n">b</span> <span class="mi">3</span><span class="n">b</span> <span class="mi">1</span><span class="n">b</span><span class="p">)</span>
168
169 <span class="n">w</span><span class="o">/</span> <span class="p">{</span>
170     <span class="mi">1</span><span class="n">b</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
171     <span class="mi">3</span><span class="n">b</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
172     <span class="mi">2</span><span class="n">b</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
173     <span class="mi">0</span><span class="n">a</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
174     <span class="p">}</span>
175
176 <span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
177 </pre></div>
178 </div>
179 <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>
180 </div>
181 <div class="section" id="compiling-popswaproll">
182 <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>
183 <p>The simplest way to “compile” this function would be something like:</p>
184 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
185     <span class="k">return</span> <span class="n">rolldown</span><span class="p">(</span><span class="o">*</span><span class="n">swap</span><span class="p">(</span><span class="o">*</span><span class="n">pop</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">)))</span>
186 </pre></div>
187 </div>
188 <p>However, internally this function would still be allocating tuples
189 (stack cells) and doing other unnecesssary work.</p>
190 <p>Looking ahead for a moment, from the stack effect comment:</p>
191 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span>
192 </pre></div>
193 </div>
194 <p>We should be able to directly write out a Python function like:</p>
195 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
196     <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
197     <span class="k">return</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
198 </pre></div>
199 </div>
200 <p>This eliminates the internal work of the first version. Because this
201 function only rearranges the stack and doesn’t do any actual processing
202 on the stack items themselves all the information needed to implement it
203 is in the stack effect comment.</p>
204 </div>
205 <div class="section" id="functions-on-stacks">
206 <h3>Functions on Stacks<a class="headerlink" href="#functions-on-stacks" title="Permalink to this headline">¶</a></h3>
207 <p>These are slightly tricky.</p>
208 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rest</span> <span class="p">(</span> <span class="p">[</span><span class="mi">1</span> <span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span> <span class="p">)</span>
209
210 <span class="n">cons</span> <span class="p">(</span> <span class="mi">1</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">1</span> <span class="o">...</span><span class="p">]</span> <span class="p">)</span>
211 </pre></div>
212 </div>
213 </div>
214 <div class="section" id="popswaproll-rest">
215 <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>
216 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span> <span class="p">([</span><span class="mi">1</span> <span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
217 </pre></div>
218 </div>
219 <p>Re-label (instead of adding left and right tags I’m just taking the next
220 available index number for the right-side stack effect comment):</p>
221 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span> <span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
222 </pre></div>
223 </div>
224 <p>Unify and update:</p>
225 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span>       <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">)</span> <span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
226                                              <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="mi">1</span><span class="p">:</span> <span class="p">[</span><span class="mi">4</span> <span class="o">...</span><span class="p">]}</span>
227 <span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span>  <span class="p">)</span> <span class="p">(</span>        <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
228 </pre></div>
229 </div>
230 <p>Apply the first rule:</p>
231 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   <span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span><span class="p">)</span> <span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
232 <span class="o">---------------------------------------</span>
233      <span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
234 </pre></div>
235 </div>
236 <p>And there we are.</p>
237 </div>
238 <div class="section" id="popswaproll-rest-rest">
239 <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>
240 <p>Let’s do it again.</p>
241 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span> <span class="p">([</span><span class="mi">1</span> <span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
242 </pre></div>
243 </div>
244 <p>Re-label (the tails of the lists on each side each get their own label):</p>
245 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span> <span class="p">([</span><span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
246 </pre></div>
247 </div>
248 <p>Unify and update (note the opening square brackets have been omited in
249 the substitution dict, this is deliberate and I’ll explain below):</p>
250 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span>   <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">]</span>  <span class="p">)</span> <span class="p">([</span><span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
251                                                     <span class="n">w</span><span class="o">/</span> <span class="p">{</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="p">:</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">}</span>
252 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">([</span><span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
253 </pre></div>
254 </div>
255 <p>How do we find <code class="docutils literal notranslate"><span class="pre">.0.]</span></code> in <code class="docutils literal notranslate"><span class="pre">[4</span> <span class="pre">.0.]</span></code> and replace it with <code class="docutils literal notranslate"><span class="pre">5</span> <span class="pre">.1.]</span></code>
256 getting the result <code class="docutils literal notranslate"><span class="pre">[4</span> <span class="pre">5</span> <span class="pre">.1.]</span></code>? This might seem hard, but because the
257 underlying structure of the Joy list is a cons-list in Python it’s
258 actually pretty easy. I’ll explain below.</p>
259 <p>Next we unify and find our two terms are the same already: <code class="docutils literal notranslate"><span class="pre">[5</span> <span class="pre">.1.]</span></code>:</p>
260 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">([</span><span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
261 </pre></div>
262 </div>
263 <p>Giving us:</p>
264 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span><span class="p">)</span> <span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
265 </pre></div>
266 </div>
267 <p>From here we apply the first rule and get:</p>
268 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">0</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
269 </pre></div>
270 </div>
271 <p>Cleaning up the labels:</p>
272 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
273 </pre></div>
274 </div>
275 <p>This is the stack effect of <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest∘rest</span></code>.</p>
276 </div>
277 <div class="section" id="popswaproll-restrest-cons">
278 <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>
279 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span> <span class="p">(</span><span class="mi">1</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">1</span> <span class="o">...</span><span class="p">])</span>
280 </pre></div>
281 </div>
282 <p>Re-label:</p>
283 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">(</span><span class="mi">6</span> <span class="p">[</span><span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
284 </pre></div>
285 </div>
286 <p>Unify:</p>
287 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">(</span><span class="mi">6</span> <span class="p">[</span><span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
288                                                      <span class="n">w</span><span class="o">/</span> <span class="p">{</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">:</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="p">}</span>
289 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="mi">2</span>      <span class="p">)</span> <span class="p">(</span><span class="mi">6</span>       <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
290                                                      <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="mi">2</span><span class="p">:</span> <span class="mi">6</span><span class="p">}</span>
291 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="mi">6</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span>        <span class="p">)</span> <span class="p">(</span>        <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
292 </pre></div>
293 </div>
294 <p>First rule:</p>
295 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="mi">6</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
296 </pre></div>
297 </div>
298 <p>Re-label:</p>
299 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">2</span> <span class="o">...</span><span class="p">])</span>
300 </pre></div>
301 </div>
302 <p>Done.</p>
303 </div>
304 <div class="section" id="popswaproll-restrestcons-cons">
305 <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>
306 <p>One more time.</p>
307 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">2</span> <span class="o">...</span><span class="p">])</span> <span class="p">(</span><span class="mi">1</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">1</span> <span class="o">...</span><span class="p">])</span>
308 </pre></div>
309 </div>
310 <p>Re-label:</p>
311 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">(</span><span class="mi">6</span> <span class="p">[</span><span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
312 </pre></div>
313 </div>
314 <p>Unify:</p>
315 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">(</span><span class="mi">6</span> <span class="p">[</span><span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span>  <span class="p">)</span>
316                                                        <span class="n">w</span><span class="o">/</span> <span class="p">{</span> <span class="o">.</span><span class="mf">2.</span><span class="p">]</span> <span class="p">:</span> <span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">}</span>
317 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="mi">3</span>        <span class="p">)</span> <span class="p">(</span><span class="mi">6</span>       <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
318                                                        <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="mi">3</span><span class="p">:</span> <span class="mi">6</span><span class="p">}</span>
319 <span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">6</span> <span class="mi">1</span> <span class="o">--</span>          <span class="p">)</span> <span class="p">(</span>        <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
320 </pre></div>
321 </div>
322 <p>First or second rule:</p>
323 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">6</span> <span class="mi">1</span> <span class="o">--</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
324 </pre></div>
325 </div>
326 <p>Clean up the labels:</p>
327 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">])</span>
328 </pre></div>
329 </div>
330 <p>And there you have it, the stack effect for
331 <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest∘rest∘cons∘cons</span></code>.</p>
332 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">])</span>
333 </pre></div>
334 </div>
335 <p>From this stack effect comment it should be possible to construct the
336 following Python code:</p>
337 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
338     <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
339     <span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
340 </pre></div>
341 </div>
342 </div>
343 </div>
344 <div class="section" id="part-ii-implementation">
345 <h2>Part II: Implementation<a class="headerlink" href="#part-ii-implementation" title="Permalink to this headline">¶</a></h2>
346 <div class="section" id="representing-stack-effect-comments-in-python">
347 <h3>Representing Stack Effect Comments in Python<a class="headerlink" href="#representing-stack-effect-comments-in-python" title="Permalink to this headline">¶</a></h3>
348 <p>I’m going to use pairs of tuples of type descriptors, which will be
349 integers or tuples of type descriptors:</p>
350 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">roll_dn</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
351
352 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()</span>
353
354 <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
355 </pre></div>
356 </div>
357 </div>
358 <div class="section" id="compose">
359 <h3><code class="docutils literal notranslate"><span class="pre">compose()</span></code><a class="headerlink" href="#compose" title="Permalink to this headline">¶</a></h3>
360 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
361
362     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
363
364     <span class="c1"># First rule.</span>
365     <span class="c1">#</span>
366     <span class="c1">#       (a -- b) (-- d)</span>
367     <span class="c1">#    ---------------------</span>
368     <span class="c1">#         (a -- b d)</span>
369
370     <span class="k">if</span> <span class="ow">not</span> <span class="n">g_in</span><span class="p">:</span>
371
372         <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span> <span class="o">=</span> <span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span> <span class="o">+</span> <span class="n">g_out</span>
373
374     <span class="c1"># Second rule.</span>
375     <span class="c1">#</span>
376     <span class="c1">#       (a --) (c -- d)</span>
377     <span class="c1">#    ---------------------</span>
378     <span class="c1">#         (c a -- d)</span>
379
380     <span class="k">elif</span> <span class="ow">not</span> <span class="n">f_out</span><span class="p">:</span>
381
382         <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span> <span class="o">=</span> <span class="n">g_in</span> <span class="o">+</span> <span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span>
383
384     <span class="k">else</span><span class="p">:</span> <span class="c1"># Unify, update, recur.</span>
385
386         <span class="n">fo</span><span class="p">,</span> <span class="n">gi</span> <span class="o">=</span> <span class="n">f_out</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">g_in</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
387
388         <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">gi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
389
390         <span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>  <span class="c1"># s can also be the empty dict, which is ok.</span>
391             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#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>
392
393         <span class="n">f_g</span> <span class="o">=</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">g_out</span><span class="p">)</span>
394
395         <span class="k">if</span> <span class="n">s</span><span class="p">:</span> <span class="n">f_g</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">f_g</span><span class="p">)</span>
396
397         <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span> <span class="o">=</span> <span class="n">compose</span><span class="p">(</span><span class="o">*</span><span class="n">f_g</span><span class="p">)</span>
398
399     <span class="k">return</span> <span class="n">fg_in</span><span class="p">,</span> <span class="n">fg_out</span>
400 </pre></div>
401 </div>
402 </div>
403 <div class="section" id="unify">
404 <h3><code class="docutils literal notranslate"><span class="pre">unify()</span></code><a class="headerlink" href="#unify" title="Permalink to this headline">¶</a></h3>
405 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
406     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
407         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
408
409     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
410         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
411     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
412         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
413     <span class="k">else</span><span class="p">:</span>
414         <span class="n">s</span> <span class="o">=</span> <span class="kc">False</span>
415
416     <span class="k">return</span> <span class="n">s</span>
417 </pre></div>
418 </div>
419 </div>
420 <div class="section" id="update">
421 <h3><code class="docutils literal notranslate"><span class="pre">update()</span></code><a class="headerlink" href="#update" title="Permalink to this headline">¶</a></h3>
422 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">term</span><span class="p">):</span>
423     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
424         <span class="k">return</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">term</span><span class="p">)</span>
425     <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">inner</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">term</span><span class="p">)</span>
426 </pre></div>
427 </div>
428 </div>
429 <div class="section" id="relabel">
430 <h3><code class="docutils literal notranslate"><span class="pre">relabel()</span></code><a class="headerlink" href="#relabel" title="Permalink to this headline">¶</a></h3>
431 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">relabel</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
432     <span class="k">return</span> <span class="n">left</span><span class="p">,</span> <span class="n">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">)</span>
433
434 <span class="k">def</span> <span class="nf">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">):</span>
435     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">right</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
436         <span class="k">return</span> <span class="mi">1000</span> <span class="o">+</span> <span class="n">right</span>
437     <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">_1000</span><span class="p">(</span><span class="n">n</span><span class="p">)</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">right</span><span class="p">)</span>
438
439 <span class="n">relabel</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
440 </pre></div>
441 </div>
442 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()),</span> <span class="p">((</span><span class="mi">1001</span><span class="p">,</span> <span class="mi">1002</span><span class="p">),</span> <span class="p">(</span><span class="mi">1002</span><span class="p">,</span> <span class="mi">1001</span><span class="p">)))</span>
443 </pre></div>
444 </div>
445 </div>
446 <div class="section" id="delabel">
447 <h3><code class="docutils literal notranslate"><span class="pre">delabel()</span></code><a class="headerlink" href="#delabel" title="Permalink to this headline">¶</a></h3>
448 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
449     <span class="n">s</span> <span class="o">=</span> <span class="p">{</span><span class="n">u</span><span class="p">:</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">u</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">_unique</span><span class="p">(</span><span class="n">f</span><span class="p">)))}</span>
450     <span class="k">return</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
451
452 <span class="k">def</span> <span class="nf">_unique</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">seen</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
453     <span class="k">if</span> <span class="n">seen</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
454         <span class="n">seen</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
455     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
456         <span class="n">seen</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
457     <span class="k">else</span><span class="p">:</span>
458         <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span>
459             <span class="n">_unique</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">seen</span><span class="p">)</span>
460     <span class="k">return</span> <span class="n">seen</span>
461
462 <span class="n">delabel</span><span class="p">(</span><span class="n">relabel</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">))</span>
463 </pre></div>
464 </div>
465 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="mi">0</span><span class="p">,),</span> <span class="p">()),</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span>
466 </pre></div>
467 </div>
468 </div>
469 <div class="section" id="c">
470 <h3><code class="docutils literal notranslate"><span class="pre">C()</span></code><a class="headerlink" href="#c" title="Permalink to this headline">¶</a></h3>
471 <p>At last we put it all together in a function <code class="docutils literal notranslate"><span class="pre">C()</span></code> that accepts two
472 stack effect comments and returns their composition (or raises and
473 exception if they can’t be composed due to type conflicts.)</p>
474 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
475     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
476     <span class="n">fg</span> <span class="o">=</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
477     <span class="k">return</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
478 </pre></div>
479 </div>
480 <p>Let’s try it out.</p>
481 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
482 </pre></div>
483 </div>
484 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
485 </pre></div>
486 </div>
487 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">),</span> <span class="n">roll_dn</span><span class="p">)</span>
488 </pre></div>
489 </div>
490 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
491 </pre></div>
492 </div>
493 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">)</span>
494 </pre></div>
495 </div>
496 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
497 </pre></div>
498 </div>
499 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
500 </pre></div>
501 </div>
502 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
503 </pre></div>
504 </div>
505 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">poswrd</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
506 <span class="n">poswrd</span>
507 </pre></div>
508 </div>
509 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
510 </pre></div>
511 </div>
512 </div>
513 <div class="section" id="stack-functions">
514 <h3>Stack Functions<a class="headerlink" href="#stack-functions" title="Permalink to this headline">¶</a></h3>
515 <p>Here’s that trick to represent functions like <code class="docutils literal notranslate"><span class="pre">rest</span></code> and <code class="docutils literal notranslate"><span class="pre">cons</span></code> that
516 manipulate stacks. We use a cons-list of tuples and give the tails their
517 own numbers. Then everything above already works.</p>
518 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,)</span>
519
520 <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),)</span>
521 </pre></div>
522 </div>
523 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">poswrd</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
524 </pre></div>
525 </div>
526 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">))</span>
527 </pre></div>
528 </div>
529 <p>Compare this to the stack effect comment we wrote above:</p>
530 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span>  <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span> <span class="p">),</span> <span class="p">(</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span>   <span class="mi">4</span>  <span class="p">))</span>
531 <span class="p">(</span>   <span class="p">[</span><span class="mi">4</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span>  <span class="mi">3</span>  <span class="mi">0</span>  <span class="o">--</span>  <span class="mi">3</span>  <span class="mi">2</span>  <span class="p">[</span><span class="o">...</span><span class="p">])</span>
532 </pre></div>
533 </div>
534 <p>The translation table, if you will, would be:</p>
535 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span>
536 <span class="mi">3</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span>
537 <span class="mi">4</span><span class="p">:</span> <span class="o">...</span><span class="p">],</span>
538 <span class="mi">1</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span>
539 <span class="mi">2</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span>
540 <span class="mi">0</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
541 <span class="p">}</span>
542 </pre></div>
543 </div>
544 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
545
546 <span class="n">F</span>
547 </pre></div>
548 </div>
549 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="mi">3</span><span class="p">,</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),))</span>
550 </pre></div>
551 </div>
552 <p>Compare with the stack effect comment and you can see it works fine:</p>
553 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="mi">4</span> <span class="mi">5</span> <span class="o">...</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="o">--</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">])</span>
554   <span class="mi">3</span> <span class="mi">4</span>  <span class="mi">5</span>   <span class="mi">1</span> <span class="mi">2</span> <span class="mi">0</span>     <span class="mi">2</span> <span class="mi">1</span>  <span class="mi">5</span>
555 </pre></div>
556 </div>
557 </div>
558 <div class="section" id="dealing-with-cons-and-uncons">
559 <h3>Dealing with <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code><a class="headerlink" href="#dealing-with-cons-and-uncons" title="Permalink to this headline">¶</a></h3>
560 <p>However, if we try to compose e.g. <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code> it won’t
561 work:</p>
562 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
563 </pre></div>
564 </div>
565 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
566     <span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
567 <span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
568     <span class="nb">print</span> <span class="n">e</span>
569 </pre></div>
570 </div>
571 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Cannot</span> <span class="n">unify</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="mi">1001</span><span class="p">,</span> <span class="mi">1002</span><span class="p">)</span><span class="o">.</span>
572 </pre></div>
573 </div>
574 <div class="section" id="unify-version-2">
575 <h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 2<a class="headerlink" href="#unify-version-2" title="Permalink to this headline">¶</a></h4>
576 <p>The problem is that the <code class="docutils literal notranslate"><span class="pre">unify()</span></code> function as written doesn’t handle
577 the case when both terms are tuples. We just have to add a clause to
578 deal with this recursively:</p>
579 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
580     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
581         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
582     <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
583         <span class="n">u</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">u</span><span class="p">)</span>
584         <span class="n">v</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
585
586     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
587         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
588
589     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
590         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
591
592     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
593
594         <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
595             <span class="c1"># Not a type error, caller passed in a bad value.</span>
596             <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>  <span class="c1"># FIXME this message sucks.</span>
597
598         <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">),</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span> <span class="o">=</span> <span class="n">u</span><span class="p">,</span> <span class="n">v</span>
599         <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
600         <span class="k">if</span> <span class="n">s</span> <span class="o">!=</span> <span class="kc">False</span><span class="p">:</span>
601             <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
602     <span class="k">else</span><span class="p">:</span>
603         <span class="n">s</span> <span class="o">=</span> <span class="kc">False</span>
604
605     <span class="k">return</span> <span class="n">s</span>
606 </pre></div>
607 </div>
608 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
609 </pre></div>
610 </div>
611 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
612 </pre></div>
613 </div>
614 </div>
615 </div>
616 </div>
617 <div class="section" id="part-iii-compiling-yin-functions">
618 <h2>Part III: Compiling Yin Functions<a class="headerlink" href="#part-iii-compiling-yin-functions" title="Permalink to this headline">¶</a></h2>
619 <p>Now consider the Python function we would like to derive:</p>
620 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
621     <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
622     <span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
623 </pre></div>
624 </div>
625 <p>And compare it to the input stack effect comment tuple we just computed:</p>
626 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
627 </pre></div>
628 </div>
629 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
630 </pre></div>
631 </div>
632 <p>The stack-de-structuring tuple has nearly the same form as our input
633 stack effect comment tuple, just in the reverse order:</p>
634 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span>
635 </pre></div>
636 </div>
637 <p>Remove the punctuation:</p>
638 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">_</span>   <span class="n">d</span>   <span class="n">c</span>   <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">))</span>
639 </pre></div>
640 </div>
641 <p>Reverse the order and compare:</p>
642 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">))</span>   <span class="n">c</span>   <span class="n">d</span>   <span class="n">_</span>
643 <span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span> <span class="p">)),</span>  <span class="mi">1</span><span class="p">,</span>  <span class="mi">2</span><span class="p">,</span>  <span class="mi">0</span><span class="p">)</span>
644 </pre></div>
645 </div>
646 <p>Eh?</p>
647 <p>And the return tuple</p>
648 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
649 </pre></div>
650 </div>
651 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),)</span>
652 </pre></div>
653 </div>
654 <p>is similar to the output stack effect comment tuple:</p>
655 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
656 <span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span> <span class="p">)),</span>      <span class="p">)</span>
657 </pre></div>
658 </div>
659 <p>This should make it pretty easy to write a Python function that accepts
660 the stack effect comment tuples and returns a new Python function
661 (either as a string of code or a function object ready to use) that
662 performs the semantics of that Joy function (described by the stack
663 effect.)</p>
664 <div class="section" id="python-identifiers">
665 <h3>Python Identifiers<a class="headerlink" href="#python-identifiers" title="Permalink to this headline">¶</a></h3>
666 <p>We want to substitute Python identifiers for the integers. I’m going to
667 repurpose <code class="docutils literal notranslate"><span class="pre">joy.parser.Symbol</span></code> class for this:</p>
668 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">defaultdict</span>
669 <span class="kn">from</span> <span class="nn">joy.parser</span> <span class="k">import</span> <span class="n">Symbol</span>
670
671
672 <span class="k">def</span> <span class="nf">_names_for</span><span class="p">():</span>
673     <span class="n">I</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">xrange</span><span class="p">(</span><span class="mi">1000</span><span class="p">))</span>
674     <span class="k">return</span> <span class="k">lambda</span><span class="p">:</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#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>
675
676
677 <span class="k">def</span> <span class="nf">identifiers</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
678     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
679         <span class="n">s</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="n">_names_for</span><span class="p">())</span>
680     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
681         <span class="k">return</span> <span class="n">s</span><span class="p">[</span><span class="n">term</span><span class="p">]</span>
682     <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">identifiers</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">term</span><span class="p">)</span>
683 </pre></div>
684 </div>
685 </div>
686 <div class="section" id="doc-from-stack-effect">
687 <h3><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code><a class="headerlink" href="#doc-from-stack-effect" title="Permalink to this headline">¶</a></h3>
688 <p>As a convenience I’ve implemented a function to convert the Python stack
689 effect comment tuples to reasonable text format. There are some details
690 in how this code works that related to stuff later in the notebook, so
691 you should skip it for now and read it later if you’re interested.</p>
692 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
693     <span class="k">return</span> <span class="s1">&#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>
694         <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>
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="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>
696     <span class="p">)</span>
697
698
699 <span class="k">def</span> <span class="nf">_to_str</span><span class="p">(</span><span class="n">term</span><span class="p">):</span>
700     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
701         <span class="k">try</span><span class="p">:</span>
702             <span class="n">t</span> <span class="o">=</span> <span class="n">term</span><span class="o">.</span><span class="n">prefix</span> <span class="o">==</span> <span class="s1">&#39;s&#39;</span>
703         <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
704             <span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
705         <span class="k">return</span> <span class="s1">&#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>
706
707     <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
708     <span class="k">while</span> <span class="n">term</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
709         <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
710         <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_to_str</span><span class="p">(</span><span class="n">item</span><span class="p">))</span>
711
712     <span class="k">try</span><span class="p">:</span>
713         <span class="n">n</span> <span class="o">=</span> <span class="n">term</span><span class="o">.</span><span class="n">number</span>
714     <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
715         <span class="n">n</span> <span class="o">=</span> <span class="n">term</span>
716     <span class="k">else</span><span class="p">:</span>
717         <span class="k">if</span> <span class="n">term</span><span class="o">.</span><span class="n">prefix</span> <span class="o">!=</span> <span class="s1">&#39;s&#39;</span><span class="p">:</span>
718             <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>
719
720     <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>
721     <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>
722 </pre></div>
723 </div>
724 </div>
725 <div class="section" id="compile">
726 <h3><code class="docutils literal notranslate"><span class="pre">compile_()</span></code><a class="headerlink" href="#compile" title="Permalink to this headline">¶</a></h3>
727 <p>Now we can write a compiler function to emit Python source code. (The
728 underscore suffix distiguishes it from the built-in <code class="docutils literal notranslate"><span class="pre">compile()</span></code>
729 function.)</p>
730 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
731     <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
732         <span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
733     <span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">identifiers</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
734     <span class="n">i</span> <span class="o">=</span> <span class="n">o</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;stack&#39;</span><span class="p">)</span>
735     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">inputs</span><span class="p">:</span>
736         <span class="n">i</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">i</span>
737     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">outputs</span><span class="p">:</span>
738         <span class="n">o</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">o</span>
739     <span class="k">return</span> <span class="s1">&#39;&#39;&#39;def </span><span class="si">%s</span><span class="s1">(stack):</span>
740 <span class="s1">    &quot;&quot;&quot;</span><span class="si">%s</span><span class="s1">&quot;&quot;&quot;</span>
741 <span class="s1">    </span><span class="si">%s</span><span class="s1"> = stack</span>
742 <span class="s1">    return </span><span class="si">%s</span><span class="s1">&#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>
743 </pre></div>
744 </div>
745 <p>Here it is in action:</p>
746 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">source</span> <span class="o">=</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;F&#39;</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
747
748 <span class="nb">print</span> <span class="n">source</span>
749 </pre></div>
750 </div>
751 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
752     <span class="sd">&quot;&quot;&quot;([3 4 .5.] 1 2 0 -- [2 1 .5.])&quot;&quot;&quot;</span>
753     <span class="p">(</span><span class="n">a5</span><span class="p">,</span> <span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">((</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a2</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
754     <span class="k">return</span> <span class="p">((</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">a2</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
755 </pre></div>
756 </div>
757 <p>Compare:</p>
758 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
759     <span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
760     <span class="k">return</span> <span class="p">((</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
761 </pre></div>
762 </div>
763 <p>Next steps:</p>
764 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="p">{}</span>
765
766 <span class="nb">eval</span><span class="p">(</span><span class="nb">compile</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="s1">&#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>
767
768 <span class="n">L</span><span class="p">[</span><span class="s1">&#39;F&#39;</span><span class="p">]</span>
769 </pre></div>
770 </div>
771 <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>
772 </pre></div>
773 </div>
774 <p>Let’s try it out:</p>
775 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
776 <span class="kn">from</span> <span class="nn">joy.library</span> <span class="k">import</span> <span class="n">SimpleFunctionWrapper</span>
777 </pre></div>
778 </div>
779 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">&#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>
780 </pre></div>
781 </div>
782 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[4 5 ...] 2 3 1 F&#39;</span><span class="p">)</span>
783 </pre></div>
784 </div>
785 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">]</span>
786 </pre></div>
787 </div>
788 <p>With this, we have a partial Joy compiler that works on the subset of
789 Joy functions that manipulate stacks (both what I call “stack chatter”
790 and the ones that manipulate stacks on the stack.)</p>
791 <p>I’m probably going to modify the definition wrapper code to detect
792 definitions that can be compiled by this partial compiler and do it
793 automatically. It might be a reasonable idea to detect sequences of
794 compilable functions in definitions that have uncompilable functions in
795 them and just compile those. However, if your library is well-factored
796 this might be less helpful.</p>
797 </div>
798 <div class="section" id="compiling-library-functions">
799 <h3>Compiling Library Functions<a class="headerlink" href="#compiling-library-functions" title="Permalink to this headline">¶</a></h3>
800 <p>We can use <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> to generate many primitives in the library
801 from their stack effect comments:</p>
802 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
803
804     <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
805
806     <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
807
808     <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()</span>
809
810     <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
811
812     <span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,)</span>
813
814     <span class="n">rrest</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
815
816     <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),)</span>
817
818     <span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
819
820     <span class="n">swons</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">cons</span><span class="p">)</span>
821
822     <span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
823 </pre></div>
824 </div>
825 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
826     <span class="nb">print</span>
827     <span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span><span class="p">)</span>
828     <span class="nb">print</span>
829 </pre></div>
830 </div>
831 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">cons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
832     <span class="sd">&quot;&quot;&quot;(1 2 -- [1 .2.])&quot;&quot;&quot;</span>
833     <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
834     <span class="k">return</span> <span class="p">((</span><span class="n">a0</span><span class="p">,</span> <span class="n">a1</span><span class="p">),</span> <span class="n">stack</span><span class="p">)</span>
835
836
837 <span class="k">def</span> <span class="nf">pop</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
838     <span class="sd">&quot;&quot;&quot;(1 --)&quot;&quot;&quot;</span>
839     <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
840     <span class="k">return</span> <span class="n">stack</span>
841
842
843 <span class="k">def</span> <span class="nf">rest</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
844     <span class="sd">&quot;&quot;&quot;([1 .2.] -- 2)&quot;&quot;&quot;</span>
845     <span class="p">((</span><span class="n">a0</span><span class="p">,</span> <span class="n">a1</span><span class="p">),</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
846     <span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
847
848
849 <span class="k">def</span> <span class="nf">rolldown</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
850     <span class="sd">&quot;&quot;&quot;(1 2 3 -- 2 3 1)&quot;&quot;&quot;</span>
851     <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
852     <span class="k">return</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
853
854
855 <span class="k">def</span> <span class="nf">rollup</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
856     <span class="sd">&quot;&quot;&quot;(1 2 3 -- 3 1 2)&quot;&quot;&quot;</span>
857     <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
858     <span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
859
860
861 <span class="k">def</span> <span class="nf">rrest</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
862     <span class="sd">&quot;&quot;&quot;([0 1 .2.] -- 2)&quot;&quot;&quot;</span>
863     <span class="p">((</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a2</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
864     <span class="k">return</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
865
866
867 <span class="k">def</span> <span class="nf">swap</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
868     <span class="sd">&quot;&quot;&quot;(1 2 -- 2 1)&quot;&quot;&quot;</span>
869     <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
870     <span class="k">return</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span>
871
872
873 <span class="k">def</span> <span class="nf">swons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
874     <span class="sd">&quot;&quot;&quot;(0 1 -- [1 .0.])&quot;&quot;&quot;</span>
875     <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
876     <span class="k">return</span> <span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="n">a0</span><span class="p">),</span> <span class="n">stack</span><span class="p">)</span>
877
878
879 <span class="k">def</span> <span class="nf">uncons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
880     <span class="sd">&quot;&quot;&quot;([1 .2.] -- 1 2)&quot;&quot;&quot;</span>
881     <span class="p">((</span><span class="n">a0</span><span class="p">,</span> <span class="n">a1</span><span class="p">),</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
882     <span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a0</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span>
883 </pre></div>
884 </div>
885 </div>
886 </div>
887 <div class="section" id="part-iv-types-and-subtypes-of-arguments">
888 <h2>Part IV: Types and Subtypes of Arguments<a class="headerlink" href="#part-iv-types-and-subtypes-of-arguments" title="Permalink to this headline">¶</a></h2>
889 <p>So far we have dealt with types of functions, those dealing with simple
890 stack manipulation. Let’s extend our machinery to deal with types of
891 arguments.</p>
892 <div class="section" id="number-type">
893 <h3>“Number” Type<a class="headerlink" href="#number-type" title="Permalink to this headline">¶</a></h3>
894 <p>Consider the definition of <code class="docutils literal notranslate"><span class="pre">sqr</span></code>:</p>
895 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sqr</span> <span class="o">==</span> <span class="n">dup</span> <span class="n">mul</span>
896 </pre></div>
897 </div>
898 <p>The <code class="docutils literal notranslate"><span class="pre">dup</span></code> function accepts one <em>anything</em> and returns two of that:</p>
899 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span> <span class="p">(</span><span class="mi">1</span> <span class="o">--</span> <span class="mi">1</span> <span class="mi">1</span><span class="p">)</span>
900 </pre></div>
901 </div>
902 <p>And <code class="docutils literal notranslate"><span class="pre">mul</span></code> accepts two “numbers” (we’re ignoring ints vs. floats vs.
903 complex, etc., for now) and returns just one:</p>
904 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span> <span class="p">(</span><span class="n">n</span> <span class="n">n</span> <span class="o">--</span> <span class="n">n</span><span class="p">)</span>
905 </pre></div>
906 </div>
907 <p>So we’re composing:</p>
908 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(1 -- 1 1)∘(n n -- n)
909 </pre></div>
910 </div>
911 <p>The rules say we unify 1 with <code class="docutils literal notranslate"><span class="pre">n</span></code>:</p>
912 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (1 -- 1 1)∘(n n -- n)
913 ---------------------------  w/  {1: n}
914    (1 -- 1  )∘(n   -- n)
915 </pre></div>
916 </div>
917 <p>This involves detecting that “Any type” arguments can accept “numbers”.
918 If we were composing these functions the other way round this is still
919 the case:</p>
920 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (n n -- n)∘(1 -- 1 1)
921 ---------------------------  w/  {1: n}
922    (n n --  )∘(  -- n n)
923 </pre></div>
924 </div>
925 <p>The important thing here is that the mapping is going the same way in
926 both cases, from the “any” integer to the number</p>
927 </div>
928 <div class="section" id="distinguishing-numbers">
929 <h3>Distinguishing Numbers<a class="headerlink" href="#distinguishing-numbers" title="Permalink to this headline">¶</a></h3>
930 <p>We should also mind that the number that <code class="docutils literal notranslate"><span class="pre">mul</span></code> produces is not
931 (necessarily) the same as either of its inputs, which are not
932 (necessarily) the same as each other:</p>
933 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>mul (n2 n1 -- n3)
934
935
936    (1  -- 1  1)∘(n2 n1 -- n3)
937 --------------------------------  w/  {1: n2}
938    (n2 -- n2  )∘(n2    -- n3)
939
940
941    (n2 n1 -- n3)∘(1 -- 1  1 )
942 --------------------------------  w/  {1: n3}
943    (n2 n1 --   )∘(  -- n3 n3)
944 </pre></div>
945 </div>
946 </div>
947 <div class="section" id="distinguishing-types">
948 <h3>Distinguishing Types<a class="headerlink" href="#distinguishing-types" title="Permalink to this headline">¶</a></h3>
949 <p>So we need separate domains of “any” numbers and “number” numbers, and
950 we need to be able to ask the order of these domains. Now the notes on
951 the right side of rule three make more sense, eh?</p>
952 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>   (a -- b t[i])∘(c u[j] -- d)   t &lt;= u (t is subtype of u)
953 -------------------------------
954    (a -- b     )∘(c      -- d)   t[i] == t[k] == u[j]
955                                          ^
956
957    (a -- b t[i])∘(c u[j] -- d)   u &lt;= t (u is subtype of t)
958 -------------------------------
959    (a -- b     )∘(c      -- d)   t[i] == u[k] == u[j]
960 </pre></div>
961 </div>
962 <p>The indices <code class="docutils literal notranslate"><span class="pre">i</span></code>, <code class="docutils literal notranslate"><span class="pre">k</span></code>, and <code class="docutils literal notranslate"><span class="pre">j</span></code> are the number part of our labels
963 and <code class="docutils literal notranslate"><span class="pre">t</span></code> and <code class="docutils literal notranslate"><span class="pre">u</span></code> are the domains.</p>
964 <p>By creative use of Python’s “double underscore” methods we can define a
965 Python class hierarchy of Joy types and use the <code class="docutils literal notranslate"><span class="pre">issubclass()</span></code> method
966 to establish domain ordering, as well as other handy behaviour that will
967 make it fairly easy to reuse most of the code above.</p>
968 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">AnyJoyType</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
969
970     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;a&#39;</span>
971
972     <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
973         <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
974
975     <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
976         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span><span class="p">)</span>
977
978     <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
979         <span class="k">return</span> <span class="p">(</span>
980             <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
981             <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">prefix</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span>
982             <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">number</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span>
983         <span class="p">)</span>
984
985     <span class="k">def</span> <span class="nf">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
986         <span class="k">return</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
987
988     <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
989         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="n">other</span><span class="p">)</span>
990     <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
991
992     <span class="k">def</span> <span class="nf">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
993         <span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
994
995
996 <span class="k">class</span> <span class="nc">NumberJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;n&#39;</span>
997 <span class="k">class</span> <span class="nc">FloatJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;f&#39;</span>
998 <span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">FloatJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;i&#39;</span>
999
1000
1001 <span class="k">class</span> <span class="nc">StackJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
1002     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;s&#39;</span>
1003
1004
1005 <span class="n">_R</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
1006 <span class="n">A</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1007 <span class="n">N</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1008 <span class="n">S</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">StackJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1009 </pre></div>
1010 </div>
1011 <p>Mess with it a little:</p>
1012 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">permutations</span>
1013 </pre></div>
1014 </div>
1015 <p>“Any” types can be specialized to numbers and stacks, but not vice
1016 versa:</p>
1017 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="mi">2</span><span class="p">):</span>
1018     <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">&#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>
1019 </pre></div>
1020 </div>
1021 <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>
1022 <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>
1023 <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>
1024 <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>
1025 <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>
1026 <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>
1027 </pre></div>
1028 </div>
1029 <p>Our crude <a class="reference external" href="https://en.wikipedia.org/wiki/Numerical_tower">Numerical
1030 Tower</a> of <em>numbers</em> &gt;
1031 <em>floats</em> &gt; <em>integers</em> works as well (but we’re not going to use it yet):</p>
1032 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">FloatJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">IntJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">)),</span> <span class="mi">2</span><span class="p">):</span>
1033     <span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">&#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>
1034 </pre></div>
1035 </div>
1036 <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>
1037 <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>
1038 <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>
1039 <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>
1040 <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>
1041 <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>
1042 <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>
1043 <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>
1044 <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>
1045 <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>
1046 <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>
1047 <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>
1048 </pre></div>
1049 </div>
1050 </div>
1051 <div class="section" id="typing-sqr">
1052 <h3>Typing <code class="docutils literal notranslate"><span class="pre">sqr</span></code><a class="headerlink" href="#typing-sqr" title="Permalink to this headline">¶</a></h3>
1053 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1054
1055 <span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],)</span>
1056 </pre></div>
1057 </div>
1058 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span>
1059 </pre></div>
1060 </div>
1061 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a1</span><span class="p">))</span>
1062 </pre></div>
1063 </div>
1064 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span>
1065 </pre></div>
1066 </div>
1067 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">),</span> <span class="p">(</span><span class="n">n3</span><span class="p">,))</span>
1068 </pre></div>
1069 </div>
1070 </div>
1071 <div class="section" id="modifying-the-inferencer">
1072 <h3>Modifying the Inferencer<a class="headerlink" href="#modifying-the-inferencer" title="Permalink to this headline">¶</a></h3>
1073 <p>Re-labeling still works fine:</p>
1074 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
1075
1076 <span class="n">foo</span>
1077 </pre></div>
1078 </div>
1079 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a1</span><span class="p">,),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a1</span><span class="p">)),</span> <span class="p">((</span><span class="n">n1001</span><span class="p">,</span> <span class="n">n1002</span><span class="p">),</span> <span class="p">(</span><span class="n">n1003</span><span class="p">,)))</span>
1080 </pre></div>
1081 </div>
1082 <div class="section" id="delabel-version-2">
1083 <h4><code class="docutils literal notranslate"><span class="pre">delabel()</span></code> version 2<a class="headerlink" href="#delabel-version-2" title="Permalink to this headline">¶</a></h4>
1084 <p>The <code class="docutils literal notranslate"><span class="pre">delabel()</span></code> function needs an overhaul. It now has to keep track
1085 of how many labels of each domain it has “seen”.</p>
1086 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">Counter</span>
1087
1088
1089 <span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">seen</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
1090     <span class="k">if</span> <span class="n">seen</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1091         <span class="k">assert</span> <span class="n">c</span> <span class="ow">is</span> <span class="kc">None</span>
1092         <span class="n">seen</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="p">{},</span> <span class="n">Counter</span><span class="p">()</span>
1093
1094     <span class="k">try</span><span class="p">:</span>
1095         <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
1096     <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
1097         <span class="k">pass</span>
1098
1099     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1100         <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
1101         <span class="n">c</span><span class="p">[</span><span class="n">f</span><span class="o">.</span><span class="n">prefix</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span>
1102         <span class="k">return</span> <span class="n">seen</span><span class="p">[</span><span class="n">f</span><span class="p">]</span>
1103
1104     <span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">delabel</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">seen</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">f</span><span class="p">)</span>
1105 </pre></div>
1106 </div>
1107 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">delabel</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
1108 </pre></div>
1109 </div>
1110 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a1</span><span class="p">,),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a1</span><span class="p">)),</span> <span class="p">((</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">),</span> <span class="p">(</span><span class="n">n3</span><span class="p">,)))</span>
1111 </pre></div>
1112 </div>
1113 </div>
1114 <div class="section" id="unify-version-3">
1115 <h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 3<a class="headerlink" href="#unify-version-3" title="Permalink to this headline">¶</a></h4>
1116 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
1117     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1118         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
1119     <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
1120         <span class="n">u</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">u</span><span class="p">)</span>
1121         <span class="n">v</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
1122
1123     <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
1124         <span class="k">return</span> <span class="n">s</span>
1125
1126     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">AnyJoyType</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">AnyJoyType</span><span class="p">):</span>
1127         <span class="k">if</span> <span class="n">u</span> <span class="o">&gt;=</span> <span class="n">v</span><span class="p">:</span>
1128             <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
1129             <span class="k">return</span> <span class="n">s</span>
1130         <span class="k">if</span> <span class="n">v</span> <span class="o">&gt;=</span> <span class="n">u</span><span class="p">:</span>
1131             <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
1132             <span class="k">return</span> <span class="n">s</span>
1133         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#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>
1134
1135     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1136         <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
1137             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>
1138         <span class="k">for</span> <span class="n">uu</span><span class="p">,</span> <span class="n">vv</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">):</span>
1139             <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">uu</span><span class="p">,</span> <span class="n">vv</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
1140             <span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span> <span class="c1"># (instead of a substitution dict.)</span>
1141                 <span class="k">break</span>
1142         <span class="k">return</span> <span class="n">s</span>
1143
1144     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1145         <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">u</span><span class="p">):</span>
1146             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#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>
1147         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
1148         <span class="k">return</span> <span class="n">s</span>
1149
1150     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1151         <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">v</span><span class="p">):</span>
1152             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#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>
1153         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
1154         <span class="k">return</span> <span class="n">s</span>
1155
1156     <span class="k">return</span> <span class="kc">False</span>
1157
1158
1159 <span class="k">def</span> <span class="nf">stacky</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
1160     <span class="k">return</span> <span class="n">thing</span><span class="o">.</span><span class="vm">__class__</span> <span class="ow">in</span> <span class="p">{</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">}</span>
1161 </pre></div>
1162 </div>
1163 <p>Rewrite the stack effect comments:</p>
1164 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
1165
1166     <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1167
1168     <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
1169
1170     <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">()</span>
1171
1172     <span class="n">popop</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">()</span>
1173
1174     <span class="n">popd</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
1175
1176     <span class="n">popdd</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
1177
1178     <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1179
1180     <span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),),</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
1181
1182     <span class="n">rrest</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
1183
1184     <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),)</span>
1185
1186     <span class="n">ccons</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)</span>
1187
1188     <span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1189
1190     <span class="n">swons</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">cons</span><span class="p">)</span>
1191
1192     <span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1193
1194     <span class="n">dupd</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1195
1196     <span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],)</span>
1197
1198     <span class="n">sqrt</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
1199
1200     <span class="n">first</span> <span class="o">=</span> <span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],)</span>
1201
1202     <span class="n">second</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">first</span><span class="p">)</span>
1203
1204     <span class="n">third</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">second</span><span class="p">)</span>
1205
1206     <span class="n">tuck</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1207
1208     <span class="n">over</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
1209
1210     <span class="n">succ</span> <span class="o">=</span> <span class="n">pred</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],)</span>
1211
1212     <span class="n">divmod_</span> <span class="o">=</span> <span class="n">pm</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span>
1213
1214     <span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
1215 </pre></div>
1216 </div>
1217 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DEFS</span> <span class="o">=</span> <span class="n">defs</span><span class="p">()</span>
1218 </pre></div>
1219 </div>
1220 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
1221     <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#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>
1222 </pre></div>
1223 </div>
1224 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ccons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1225 <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1226 <span class="n">divmod_</span> <span class="o">=</span> <span class="p">(</span><span class="n">n2</span> <span class="n">n1</span> <span class="o">--</span> <span class="n">n4</span> <span class="n">n3</span><span class="p">)</span>
1227 <span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span>
1228 <span class="n">dupd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1229 <span class="n">first</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
1230 <span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="n">n2</span> <span class="o">--</span> <span class="n">n3</span><span class="p">)</span>
1231 <span class="n">over</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
1232 <span class="n">pm</span> <span class="o">=</span> <span class="p">(</span><span class="n">n2</span> <span class="n">n1</span> <span class="o">--</span> <span class="n">n4</span> <span class="n">n3</span><span class="p">)</span>
1233 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
1234 <span class="n">popd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
1235 <span class="n">popdd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1236 <span class="n">popop</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
1237 <span class="n">pred</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
1238 <span class="n">rest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1239 <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a1</span><span class="p">)</span>
1240 <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
1241 <span class="n">rrest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1242 <span class="n">second</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
1243 <span class="n">sqrt</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
1244 <span class="n">succ</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
1245 <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1246 <span class="n">swons</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1247 <span class="n">third</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a3</span><span class="p">)</span>
1248 <span class="n">tuck</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1249 <span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1250 </pre></div>
1251 </div>
1252 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">DEFS</span><span class="p">)</span>
1253 </pre></div>
1254 </div>
1255 </div>
1256 <div class="section" id="compose-dup-and-mul">
1257 <h4>Compose <code class="docutils literal notranslate"><span class="pre">dup</span></code> and <code class="docutils literal notranslate"><span class="pre">mul</span></code><a class="headerlink" href="#compose-dup-and-mul" title="Permalink to this headline">¶</a></h4>
1258 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
1259 </pre></div>
1260 </div>
1261 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">n1</span><span class="p">,),</span> <span class="p">(</span><span class="n">n2</span><span class="p">,))</span>
1262 </pre></div>
1263 </div>
1264 <p>Revisit the <code class="docutils literal notranslate"><span class="pre">F</span></code> function, works fine.</p>
1265 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
1266 <span class="n">F</span>
1267 </pre></div>
1268 </div>
1269 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">a3</span><span class="p">,</span> <span class="n">a4</span><span class="p">,</span> <span class="n">a5</span><span class="p">),</span> <span class="p">((</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),))</span>
1270 </pre></div>
1271 </div>
1272 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
1273 </pre></div>
1274 </div>
1275 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a3</span> <span class="n">a4</span> <span class="n">a5</span> <span class="o">--</span> <span class="p">[</span><span class="n">a4</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1276 </pre></div>
1277 </div>
1278 <p>Some otherwise inefficient functions are no longer to be feared. We can
1279 also get the effect of combinators in some limited cases.</p>
1280 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">neato</span><span class="p">(</span><span class="o">*</span><span class="n">funcs</span><span class="p">):</span>
1281     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">funcs</span><span class="p">))</span>
1282 </pre></div>
1283 </div>
1284 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [swap] dip</span>
1285 <span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">)</span>
1286 </pre></div>
1287 </div>
1288 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a3</span><span class="p">)</span>
1289 </pre></div>
1290 </div>
1291 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [popop] dipd</span>
1292 <span class="n">neato</span><span class="p">(</span><span class="n">popdd</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">pop</span><span class="p">)</span>
1293 </pre></div>
1294 </div>
1295 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a4</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a4</span><span class="p">)</span>
1296 </pre></div>
1297 </div>
1298 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Reverse the order of the top three items.</span>
1299 <span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
1300 </pre></div>
1301 </div>
1302 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1303 </pre></div>
1304 </div>
1305 </div>
1306 <div class="section" id="compile-version-2">
1307 <h4><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 2<a class="headerlink" href="#compile-version-2" title="Permalink to this headline">¶</a></h4>
1308 <p>Because the type labels represent themselves as valid Python identifiers
1309 the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function doesn’t need to generate them anymore:</p>
1310 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
1311     <span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">f</span>
1312     <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1313         <span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">)</span>
1314     <span class="n">i</span> <span class="o">=</span> <span class="n">o</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">&#39;stack&#39;</span><span class="p">)</span>
1315     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">inputs</span><span class="p">:</span>
1316         <span class="n">i</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">i</span>
1317     <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">outputs</span><span class="p">:</span>
1318         <span class="n">o</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">o</span>
1319     <span class="k">return</span> <span class="s1">&#39;&#39;&#39;def </span><span class="si">%s</span><span class="s1">(stack):</span>
1320 <span class="s1">    &quot;&quot;&quot;</span><span class="si">%s</span><span class="s1">&quot;&quot;&quot;</span>
1321 <span class="s1">    </span><span class="si">%s</span><span class="s1"> = stack</span>
1322 <span class="s1">    return </span><span class="si">%s</span><span class="s1">&#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>
1323 </pre></div>
1324 </div>
1325 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;F&#39;</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
1326 </pre></div>
1327 </div>
1328 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
1329     <span class="sd">&quot;&quot;&quot;([a1 a2 .1.] a3 a4 a5 -- [a4 a3 .1.])&quot;&quot;&quot;</span>
1330     <span class="p">(</span><span class="n">a5</span><span class="p">,</span> <span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
1331     <span class="k">return</span> <span class="p">((</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
1332 </pre></div>
1333 </div>
1334 <p>But it cannot magically create new functions that involve e.g. math and
1335 such. Note that this is <em>not</em> a <code class="docutils literal notranslate"><span class="pre">sqr</span></code> function implementation:</p>
1336 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#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>
1337 </pre></div>
1338 </div>
1339 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sqr</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
1340     <span class="sd">&quot;&quot;&quot;(n1 -- n2)&quot;&quot;&quot;</span>
1341     <span class="p">(</span><span class="n">n1</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
1342     <span class="k">return</span> <span class="p">(</span><span class="n">n2</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
1343 </pre></div>
1344 </div>
1345 <p>(Eventually I should come back around to this becuase it’s not tooo
1346 difficult to exend this code to be able to compile e.g.
1347 <code class="docutils literal notranslate"><span class="pre">n2</span> <span class="pre">=</span> <span class="pre">mul(n1,</span> <span class="pre">n1)</span></code> for <code class="docutils literal notranslate"><span class="pre">mul</span></code> with the right variable names and
1348 insert it in the right place. It requires a little more support from the
1349 library functions, in that we need to know to call <code class="docutils literal notranslate"><span class="pre">mul()</span></code> the Python
1350 function for <code class="docutils literal notranslate"><span class="pre">mul</span></code> the Joy function, but since <em>most</em> of the math
1351 functions (at least) are already wrappers it should be straightforward.)</p>
1352 </div>
1353 <div class="section" id="compilable">
1354 <h4><code class="docutils literal notranslate"><span class="pre">compilable()</span></code><a class="headerlink" href="#compilable" title="Permalink to this headline">¶</a></h4>
1355 <p>The functions that <em>can</em> be compiled are the ones that have only
1356 <code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> and <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> labels in their stack effect
1357 comments. We can write a function to check that:</p>
1358 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">imap</span>
1359
1360
1361 <span class="k">def</span> <span class="nf">compilable</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
1362     <span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">all</span><span class="p">(</span><span class="n">imap</span><span class="p">(</span><span class="n">compilable</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span> <span class="ow">or</span> <span class="n">stacky</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
1363 </pre></div>
1364 </div>
1365 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
1366     <span class="k">if</span> <span class="n">compilable</span><span class="p">(</span><span class="n">stack_effect_comment</span><span class="p">):</span>
1367         <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#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>
1368 </pre></div>
1369 </div>
1370 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ccons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1371 <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1372 <span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span>
1373 <span class="n">dupd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1374 <span class="n">first</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
1375 <span class="n">over</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
1376 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
1377 <span class="n">popd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
1378 <span class="n">popdd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1379 <span class="n">popop</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
1380 <span class="n">rest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1381 <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a1</span><span class="p">)</span>
1382 <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
1383 <span class="n">rrest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1384 <span class="n">second</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
1385 <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1386 <span class="n">swons</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1387 <span class="n">third</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a3</span><span class="p">)</span>
1388 <span class="n">tuck</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1389 <span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1390 </pre></div>
1391 </div>
1392 </div>
1393 </div>
1394 </div>
1395 <div class="section" id="part-v-functions-that-use-the-stack">
1396 <h2>Part V: Functions that use the Stack<a class="headerlink" href="#part-v-functions-that-use-the-stack" title="Permalink to this headline">¶</a></h2>
1397 <p>Consider the <code class="docutils literal notranslate"><span class="pre">stack</span></code> function which grabs the whole stack, quotes it,
1398 and puts it on itself:</p>
1399 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stack</span> <span class="p">(</span><span class="o">...</span>     <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="o">...</span><span class="p">]</span>        <span class="p">)</span>
1400 <span class="n">stack</span> <span class="p">(</span><span class="o">...</span> <span class="n">a</span>   <span class="o">--</span> <span class="o">...</span> <span class="n">a</span> <span class="p">[</span><span class="n">a</span> <span class="o">...</span><span class="p">]</span>    <span class="p">)</span>
1401 <span class="n">stack</span> <span class="p">(</span><span class="o">...</span> <span class="n">b</span> <span class="n">a</span> <span class="o">--</span> <span class="o">...</span> <span class="n">b</span> <span class="n">a</span> <span class="p">[</span><span class="n">a</span> <span class="n">b</span> <span class="o">...</span><span class="p">])</span>
1402 </pre></div>
1403 </div>
1404 <p>We would like to represent this in Python somehow. To do this we use a
1405 simple, elegant trick.</p>
1406 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stack</span>         <span class="n">S</span>   <span class="o">--</span> <span class="p">(</span>         <span class="n">S</span><span class="p">,</span>           <span class="n">S</span><span class="p">)</span>
1407 <span class="n">stack</span>     <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span>  <span class="o">--</span> <span class="p">(</span>     <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">S</span><span class="p">),</span>      <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">S</span><span class="p">))</span>
1408 <span class="n">stack</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S</span><span class="p">))</span> <span class="o">--</span> <span class="p">(</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S</span><span class="p">)),</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S</span><span class="p">)))</span>
1409 </pre></div>
1410 </div>
1411 <p>Instead of representing the stack effect comments as a single tuple
1412 (with N items in it) we use the same cons-list structure to hold the
1413 sequence and <code class="docutils literal notranslate"><span class="pre">unify()</span></code> the whole comments.</p>
1414 <div class="section" id="stackuncons">
1415 <h3><code class="docutils literal notranslate"><span class="pre">stack∘uncons</span></code><a class="headerlink" href="#stackuncons" title="Permalink to this headline">¶</a></h3>
1416 <p>Let’s try composing <code class="docutils literal notranslate"><span class="pre">stack</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code>. We want this result:</p>
1417 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>stack∘uncons (... a -- ... a a [...])
1418 </pre></div>
1419 </div>
1420 <p>The stack effects are:</p>
1421 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stack</span> <span class="o">=</span> <span class="n">S</span> <span class="o">--</span> <span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span>
1422
1423 <span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="n">Z</span><span class="p">),</span> <span class="n">S</span><span class="p">)</span> <span class="o">--</span> <span class="p">(</span><span class="n">Z</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">S</span><span class="p">))</span>
1424 </pre></div>
1425 </div>
1426 <p>Unifying:</p>
1427 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>  S    -- (S, S) ∘ ((a, Z), S) -- (Z, (a,   S   ))
1428                                                     w/ { S: (a, Z) }
1429 (a, Z) --        ∘             -- (Z, (a, (a, Z)))
1430 </pre></div>
1431 </div>
1432 <p>So:</p>
1433 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>stack∘uncons == (a, Z) -- (Z, (a, (a, Z)))
1434 </pre></div>
1435 </div>
1436 <p>It works.</p>
1437 </div>
1438 <div class="section" id="stackunconsuncons">
1439 <h3><code class="docutils literal notranslate"><span class="pre">stack∘uncons∘uncons</span></code><a class="headerlink" href="#stackunconsuncons" title="Permalink to this headline">¶</a></h3>
1440 <p>Let’s try <code class="docutils literal notranslate"><span class="pre">stack∘uncons∘uncons</span></code>:</p>
1441 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(a, S     ) -- (S,      (a, (a, S     ))) ∘ ((b, Z),  S`             ) -- (Z, (b,   S`   ))
1442
1443                                                                                 w/ { S: (b, Z) }
1444
1445 (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z),  S`             ) -- (Z, (b,   S`   ))
1446
1447                                                                                 w/ { S`: (a, (a, (b, Z))) }
1448
1449 (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), (a, (a, (b, Z)))) -- (Z, (b, (a, (a, (b, Z)))))
1450
1451 (a, (b, Z)) -- (Z, (b, (a, (a, (b, Z)))))
1452 </pre></div>
1453 </div>
1454 <p>It works.</p>
1455 <div class="section" id="compose-version-2">
1456 <h4><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 2<a class="headerlink" href="#compose-version-2" title="Permalink to this headline">¶</a></h4>
1457 <p>This function has to be modified to use the new datastructures and it is
1458 no longer recursive, instead recursion happens as part of unification.
1459 Further, the first and second of Pöial’s rules are now handled
1460 automatically by the unification algorithm. (One easy way to see this is
1461 that now an empty stack effect comment is represented by a
1462 <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> instance which is not “falsey” and so neither of the
1463 first two rules’ <code class="docutils literal notranslate"><span class="pre">if</span></code> clauses will ever be <code class="docutils literal notranslate"><span class="pre">True</span></code>. Later on I change
1464 the “truthiness” of <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> to false to let e.g.
1465 <code class="docutils literal notranslate"><span class="pre">joy.utils.stack.concat</span></code> work with our stack effect comment cons-list
1466 tuples.)</p>
1467 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
1468     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
1469     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
1470     <span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>  <span class="c1"># s can also be the empty dict, which is ok.</span>
1471         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#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>
1472     <span class="k">return</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">))</span>
1473 </pre></div>
1474 </div>
1475 <p>I don’t want to rewrite all the defs myself, so I’ll write a little
1476 conversion function instead. This is programmer’s laziness.</p>
1477 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sequence_to_stack</span><span class="p">(</span><span class="n">seq</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="n">StackJoyType</span><span class="p">(</span><span class="mi">23</span><span class="p">)):</span>
1478     <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">seq</span><span class="p">:</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">stack</span>
1479     <span class="k">return</span> <span class="n">stack</span>
1480
1481 <span class="n">NEW_DEFS</span> <span class="o">=</span> <span class="p">{</span>
1482     <span class="n">name</span><span class="p">:</span> <span class="p">(</span><span class="n">sequence_to_stack</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="n">sequence_to_stack</span><span class="p">(</span><span class="n">o</span><span class="p">))</span>
1483     <span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span> <span class="ow">in</span> <span class="n">DEFS</span><span class="o">.</span><span class="n">iteritems</span><span class="p">()</span>
1484 <span class="p">}</span>
1485 <span class="n">NEW_DEFS</span><span class="p">[</span><span class="s1">&#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>
1486 <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>
1487 <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="p">)</span>
1488 </pre></div>
1489 </div>
1490 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
1491 </pre></div>
1492 </div>
1493 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))))</span>
1494 </pre></div>
1495 </div>
1496 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
1497 </pre></div>
1498 </div>
1499 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">))))))</span>
1500 </pre></div>
1501 </div>
1502 <p>The display function should be changed too.</p>
1503 </div>
1504 </div>
1505 <div class="section" id="doc-from-stack-effect-version-2">
1506 <h3><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code> version 2<a class="headerlink" href="#doc-from-stack-effect-version-2" title="Permalink to this headline">¶</a></h3>
1507 <p>Clunky junk, but it will suffice for now.</p>
1508 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
1509     <span class="n">switch</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span><span class="p">]</span>  <span class="c1"># Do we need to display the &#39;...&#39; for the rest of the main stack?</span>
1510     <span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">_f</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">),</span> <span class="n">_f</span><span class="p">(</span><span class="n">outputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">)</span>
1511     <span class="k">if</span> <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
1512         <span class="n">i</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;...&#39;</span><span class="p">)</span>
1513         <span class="n">o</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s1">&#39;...&#39;</span><span class="p">)</span>
1514     <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>
1515         <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>
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="n">o</span> <span class="o">+</span> <span class="p">[</span><span class="s1">&#39;&#39;</span><span class="p">])),</span>
1517     <span class="p">)</span>
1518
1519
1520 <span class="k">def</span> <span class="nf">_f</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">switch</span><span class="p">):</span>
1521     <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
1522     <span class="k">while</span> <span class="n">term</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1523         <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
1524         <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
1525     <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
1526     <span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="n">_to_str</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">term</span><span class="p">,</span> <span class="n">switch</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">a</span><span class="p">]</span>
1527     <span class="k">return</span> <span class="n">a</span>
1528
1529
1530 <span class="k">def</span> <span class="nf">_to_str</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">switch</span><span class="p">):</span>
1531     <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1532         <span class="k">if</span> <span class="n">term</span> <span class="o">==</span> <span class="n">stack</span><span class="p">:</span>
1533             <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
1534             <span class="k">return</span> <span class="s1">&#39;[...]&#39;</span>
1535         <span class="k">return</span> <span class="p">(</span>
1536             <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>
1537             <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">)</span>
1538             <span class="k">else</span> <span class="nb">str</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
1539         <span class="p">)</span>
1540
1541     <span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
1542     <span class="k">while</span> <span class="n">term</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1543         <span class="n">item</span><span class="p">,</span> <span class="n">term</span> <span class="o">=</span> <span class="n">term</span>
1544         <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">_to_str</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">switch</span><span class="p">))</span>
1545     <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">term</span><span class="p">)</span>
1546     <span class="k">if</span> <span class="n">term</span> <span class="o">==</span> <span class="n">stack</span><span class="p">:</span>
1547         <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
1548         <span class="n">end</span> <span class="o">=</span> <span class="s1">&#39;...&#39;</span>
1549     <span class="k">else</span><span class="p">:</span>
1550         <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>
1551     <span class="n">a</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">end</span><span class="p">)</span>
1552     <span class="k">return</span> <span class="s1">&#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>
1553 </pre></div>
1554 </div>
1555 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
1556     <span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">&#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>
1557 </pre></div>
1558 </div>
1559 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ccons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1560 <span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1561 <span class="n">divmod_</span> <span class="o">=</span> <span class="p">(</span><span class="n">n2</span> <span class="n">n1</span> <span class="o">--</span> <span class="n">n4</span> <span class="n">n3</span><span class="p">)</span>
1562 <span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span>
1563 <span class="n">dupd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1564 <span class="n">first</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
1565 <span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="n">n2</span> <span class="o">--</span> <span class="n">n3</span><span class="p">)</span>
1566 <span class="n">over</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
1567 <span class="n">pm</span> <span class="o">=</span> <span class="p">(</span><span class="n">n2</span> <span class="n">n1</span> <span class="o">--</span> <span class="n">n4</span> <span class="n">n3</span><span class="p">)</span>
1568 <span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
1569 <span class="n">popd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
1570 <span class="n">popdd</span> <span class="o">=</span> <span class="p">(</span><span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1571 <span class="n">popop</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
1572 <span class="n">pred</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
1573 <span class="n">rest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1574 <span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a1</span><span class="p">)</span>
1575 <span class="n">rollup</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
1576 <span class="n">rrest</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1577 <span class="n">second</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
1578 <span class="n">sqrt</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
1579 <span class="n">stack</span> <span class="o">=</span> <span class="p">(</span><span class="o">...</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
1580 <span class="n">succ</span> <span class="o">=</span> <span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
1581 <span class="n">swaack</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
1582 <span class="n">swap</span> <span class="o">=</span> <span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1583 <span class="n">swons</span> <span class="o">=</span> <span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1584 <span class="n">third</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a3</span><span class="p">)</span>
1585 <span class="n">tuck</span> <span class="o">=</span> <span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
1586 <span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1587 </pre></div>
1588 </div>
1589 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack</span><span class="p">)</span>
1590 <span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
1591 <span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)))</span>
1592 <span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)))</span>
1593 </pre></div>
1594 </div>
1595 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
1596
1597 <span class="p">(</span><span class="o">...</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a1</span> <span class="n">a1</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
1598
1599 <span class="p">(</span><span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a1</span> <span class="n">a2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
1600
1601 <span class="p">(</span><span class="o">...</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a1</span> <span class="p">[</span><span class="n">a1</span> <span class="o">...</span><span class="p">])</span>
1602 </pre></div>
1603 </div>
1604 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span>
1605 </pre></div>
1606 </div>
1607 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">[[</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">...</span><span class="p">])</span>
1608 </pre></div>
1609 </div>
1610 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Q</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
1611
1612 <span class="n">Q</span>
1613 </pre></div>
1614 </div>
1615 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s2</span><span class="p">))),</span> <span class="p">(((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">),</span> <span class="p">((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">)))</span>
1616 </pre></div>
1617 </div>
1618 <div class="section" id="compile-version-3">
1619 <h4><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 3<a class="headerlink" href="#compile-version-3" title="Permalink to this headline">¶</a></h4>
1620 <p>This makes the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function pretty simple as the stack effect
1621 comments are now already in the form needed for the Python code:</p>
1622 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
1623     <span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">f</span>
1624     <span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1625         <span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
1626     <span class="k">return</span> <span class="s1">&#39;&#39;&#39;def </span><span class="si">%s</span><span class="s1">(stack):</span>
1627 <span class="s1">    &quot;&quot;&quot;</span><span class="si">%s</span><span class="s1">&quot;&quot;&quot;</span>
1628 <span class="s1">    </span><span class="si">%s</span><span class="s1"> = stack</span>
1629 <span class="s1">    return </span><span class="si">%s</span><span class="s1">&#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>
1630 </pre></div>
1631 </div>
1632 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">&#39;Q&#39;</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span>
1633 </pre></div>
1634 </div>
1635 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">Q</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
1636     <span class="sd">&quot;&quot;&quot;(... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])&quot;&quot;&quot;</span>
1637     <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s2</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
1638     <span class="k">return</span> <span class="p">(((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">),</span> <span class="p">((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">))</span>
1639 </pre></div>
1640 </div>
1641 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">unstack</span> <span class="o">=</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
1642 <span class="n">enstacken</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1643 </pre></div>
1644 </div>
1645 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">unstack</span><span class="p">)</span>
1646 </pre></div>
1647 </div>
1648 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span><span class="p">)</span>
1649 </pre></div>
1650 </div>
1651 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">enstacken</span><span class="p">)</span>
1652 </pre></div>
1653 </div>
1654 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
1655 </pre></div>
1656 </div>
1657 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">))</span>
1658 </pre></div>
1659 </div>
1660 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
1661 </pre></div>
1662 </div>
1663 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">enstacken</span><span class="p">))</span>
1664 </pre></div>
1665 </div>
1666 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
1667 </pre></div>
1668 </div>
1669 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">)</span>
1670 </pre></div>
1671 </div>
1672 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span>
1673 </pre></div>
1674 </div>
1675 </div>
1676 </div>
1677 </div>
1678 <div class="section" id="part-vi-multiple-stack-effects">
1679 <h2>Part VI: Multiple Stack Effects<a class="headerlink" href="#part-vi-multiple-stack-effects" title="Permalink to this headline">¶</a></h2>
1680 <p>…</p>
1681 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;i&#39;</span>
1682
1683
1684 <span class="n">F</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">FloatJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1685 <span class="n">I</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">IntJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1686 </pre></div>
1687 </div>
1688 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">muls</span> <span class="o">=</span> <span class="p">[</span>
1689      <span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
1690      <span class="p">((</span><span class="n">F</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
1691      <span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
1692      <span class="p">((</span><span class="n">F</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
1693 <span class="p">]</span>
1694 </pre></div>
1695 </div>
1696 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
1697     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
1698 </pre></div>
1699 </div>
1700 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">i1</span> <span class="n">i2</span> <span class="o">--</span> <span class="n">i3</span><span class="p">)</span>
1701 <span class="p">(</span><span class="n">i1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span>
1702 <span class="p">(</span><span class="n">f1</span> <span class="n">i2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span>
1703 <span class="p">(</span><span class="n">f1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span>
1704 </pre></div>
1705 </div>
1706 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
1707     <span class="k">try</span><span class="p">:</span>
1708         <span class="n">e</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
1709     <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
1710         <span class="k">continue</span>
1711     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">dup</span><span class="p">),</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">),</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">e</span><span class="p">)</span>
1712 </pre></div>
1713 </div>
1714 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span> <span class="p">(</span><span class="n">i1</span> <span class="n">i2</span> <span class="o">--</span> <span class="n">i3</span><span class="p">)</span> <span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
1715 <span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span> <span class="p">(</span><span class="n">f1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span> <span class="p">(</span><span class="n">f1</span> <span class="o">--</span> <span class="n">f2</span><span class="p">)</span>
1716 </pre></div>
1717 </div>
1718 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">product</span>
1719
1720
1721 <span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
1722     <span class="k">for</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">product</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
1723         <span class="k">try</span><span class="p">:</span>
1724             <span class="k">yield</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
1725         <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
1726             <span class="k">pass</span>
1727
1728
1729 <span class="k">def</span> <span class="nf">MC</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
1730     <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">)))</span>
1731 </pre></div>
1732 </div>
1733 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
1734     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
1735 </pre></div>
1736 </div>
1737 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
1738 </pre></div>
1739 </div>
1740 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
1741     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
1742 </pre></div>
1743 </div>
1744 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">f1</span> <span class="o">--</span> <span class="n">f2</span><span class="p">)</span>
1745 <span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
1746 </pre></div>
1747 </div>
1748 <div class="section" id="representing-an-unbounded-sequence-of-types">
1749 <h3>Representing an Unbounded Sequence of Types<a class="headerlink" href="#representing-an-unbounded-sequence-of-types" title="Permalink to this headline">¶</a></h3>
1750 <p>We can borrow a trick from <a class="reference external" href="https://en.wikipedia.org/wiki/Brzozowski_derivative">Brzozowski’s Derivatives of Regular
1751 Expressions</a> to
1752 invent a new type of type variable, a “sequence type” (I think this is
1753 what they mean in the literature by that term…) or “<a class="reference external" href="https://en.wikipedia.org/wiki/Kleene_star">Kleene
1754 Star</a>” type. I’m going to
1755 represent it as a type letter and the asterix, so a sequence of zero or
1756 more <code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> variables would be:</p>
1757 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span><span class="o">*</span>
1758 </pre></div>
1759 </div>
1760 <p>The <code class="docutils literal notranslate"><span class="pre">A*</span></code> works by splitting the universe into two alternate histories:</p>
1761 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span><span class="o">*</span> <span class="o">-&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>
1762 </pre></div>
1763 </div>
1764 <p>The Kleene star variable disappears in one universe, and in the other it
1765 turns into an <code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> variable followed by itself again. We have
1766 to return all universes (represented by their substitution dicts, the
1767 “unifiers”) that don’t lead to type conflicts.</p>
1768 <p>Consider unifying two stacks (the lowercase letters are any type
1769 variables of the kinds we have defined so far):</p>
1770 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">a</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span><span class="n">c</span> <span class="n">d</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1771                           <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="n">c</span><span class="p">:</span> <span class="n">a</span><span class="p">}</span>
1772 <span class="p">[</span>  <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span>  <span class="n">d</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1773 </pre></div>
1774 </div>
1775 <p>Now we have to split universes to unify <code class="docutils literal notranslate"><span class="pre">A*</span></code>. In the first universe it
1776 disappears:</p>
1777 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span><span class="n">d</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1778                    <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="n">d</span><span class="p">:</span> <span class="n">b</span><span class="p">,</span> <span class="o">.</span><span class="mf">1.</span><span class="p">:</span> <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
1779      <span class="p">[]</span> <span class="n">U</span> <span class="p">[]</span>
1780 </pre></div>
1781 </div>
1782 <p>While in the second it spawns an <code class="docutils literal notranslate"><span class="pre">A</span></code>, which we will label <code class="docutils literal notranslate"><span class="pre">e</span></code>:</p>
1783 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">e</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span><span class="n">d</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1784                         <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="n">d</span><span class="p">:</span> <span class="n">e</span><span class="p">}</span>
1785 <span class="p">[</span>  <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span>  <span class="o">.</span><span class="mf">1.</span><span class="p">]</span>
1786                         <span class="n">w</span><span class="o">/</span> <span class="p">{</span><span class="o">.</span><span class="mf">1.</span><span class="p">:</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
1787 <span class="p">[</span>  <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span> <span class="n">U</span> <span class="p">[</span>  <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">]</span>
1788 </pre></div>
1789 </div>
1790 <p>Giving us two unifiers:</p>
1791 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">c</span><span class="p">:</span> <span class="n">a</span><span class="p">,</span>  <span class="n">d</span><span class="p">:</span> <span class="n">b</span><span class="p">,</span>  <span class="o">.</span><span class="mf">1.</span><span class="p">:</span>      <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
1792 <span class="p">{</span><span class="n">c</span><span class="p">:</span> <span class="n">a</span><span class="p">,</span>  <span class="n">d</span><span class="p">:</span> <span class="n">e</span><span class="p">,</span>  <span class="o">.</span><span class="mf">1.</span><span class="p">:</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
1793 </pre></div>
1794 </div>
1795 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">KleeneStar</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
1796
1797     <span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
1798
1799     <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
1800         <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
1801         <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
1802         <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
1803
1804     <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1805         <span class="k">return</span> <span class="s1">&#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>
1806
1807     <span class="k">def</span> <span class="nf">another</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1808         <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
1809         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span><span class="p">(</span><span class="mi">10000</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">count</span><span class="p">)</span>
1810
1811     <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
1812         <span class="k">return</span> <span class="p">(</span>
1813             <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
1814             <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">number</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span>
1815         <span class="p">)</span>
1816
1817     <span class="k">def</span> <span class="nf">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
1818         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span> <span class="o">&gt;=</span> <span class="n">other</span><span class="o">.</span><span class="n">kind</span>
1819
1820     <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
1821         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="n">other</span><span class="p">)</span>
1822     <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
1823
1824     <span class="k">def</span> <span class="nf">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
1825         <span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
1826
1827 <span class="k">class</span> <span class="nc">AnyStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
1828 <span class="k">class</span> <span class="nc">NumberStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">NumberJoyType</span>
1829 <span class="c1">#class FloatStarJoyType(KleeneStar): kind = FloatJoyType</span>
1830 <span class="c1">#class IntStarJoyType(KleeneStar): kind = IntJoyType</span>
1831 <span class="k">class</span> <span class="nc">StackStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">StackJoyType</span>
1832
1833
1834 <span class="n">As</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">AnyStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1835 <span class="n">Ns</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">NumberStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1836 <span class="n">Ss</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">StackStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
1837 </pre></div>
1838 </div>
1839 <div class="section" id="unify-version-4">
1840 <h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 4<a class="headerlink" href="#unify-version-4" title="Permalink to this headline">¶</a></h4>
1841 <p>Can now return multiple results…</p>
1842 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
1843     <span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
1844         <span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
1845     <span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
1846         <span class="n">u</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">u</span><span class="p">)</span>
1847         <span class="n">v</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span>
1848
1849     <span class="k">if</span> <span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">:</span>
1850         <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1851
1852     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">AnyJoyType</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">AnyJoyType</span><span class="p">):</span>
1853         <span class="k">if</span> <span class="n">u</span> <span class="o">&gt;=</span> <span class="n">v</span><span class="p">:</span>
1854             <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
1855             <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1856         <span class="k">if</span> <span class="n">v</span> <span class="o">&gt;=</span> <span class="n">u</span><span class="p">:</span>
1857             <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
1858             <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1859         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#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>
1860
1861     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1862         <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">u</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">2</span><span class="p">:</span>
1863             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="nb">repr</span><span class="p">((</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)))</span>
1864
1865         <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">v</span>
1866         <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">KleeneStar</span><span class="p">):</span>
1867             <span class="c1"># Two universes, in one the Kleene star disappears and unification</span>
1868             <span class="c1"># continues without it...</span>
1869             <span class="n">s0</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
1870
1871             <span class="c1"># In the other it spawns a new variable.</span>
1872             <span class="n">s1</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">another</span><span class="p">(),</span> <span class="n">v</span><span class="p">))</span>
1873
1874             <span class="n">t</span> <span class="o">=</span> <span class="n">s0</span> <span class="o">+</span> <span class="n">s1</span>
1875             <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">t</span><span class="p">:</span>
1876                 <span class="n">sn</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
1877             <span class="k">return</span> <span class="n">t</span>
1878
1879         <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="n">u</span>
1880         <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">KleeneStar</span><span class="p">):</span>
1881             <span class="n">s0</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
1882             <span class="n">s1</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="o">.</span><span class="n">another</span><span class="p">(),</span> <span class="n">u</span><span class="p">))</span>
1883             <span class="n">t</span> <span class="o">=</span> <span class="n">s0</span> <span class="o">+</span> <span class="n">s1</span>
1884             <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">t</span><span class="p">:</span>
1885                 <span class="n">sn</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
1886             <span class="k">return</span> <span class="n">t</span>
1887
1888         <span class="n">ses</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">s</span><span class="p">)</span>
1889         <span class="n">results</span> <span class="o">=</span> <span class="p">()</span>
1890         <span class="k">for</span> <span class="n">sn</span> <span class="ow">in</span> <span class="n">ses</span><span class="p">:</span>
1891             <span class="n">results</span> <span class="o">+=</span> <span class="n">unify</span><span class="p">(</span><span class="n">u</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">v</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">sn</span><span class="p">)</span>
1892         <span class="k">return</span> <span class="n">results</span>
1893
1894     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1895         <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">u</span><span class="p">):</span>
1896             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#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>
1897         <span class="n">s</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
1898         <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1899
1900     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
1901         <span class="k">if</span> <span class="ow">not</span> <span class="n">stacky</span><span class="p">(</span><span class="n">v</span><span class="p">):</span>
1902             <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#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>
1903         <span class="n">s</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">u</span>
1904         <span class="k">return</span> <span class="n">s</span><span class="p">,</span>
1905
1906     <span class="k">return</span> <span class="p">()</span>
1907
1908
1909 <span class="k">def</span> <span class="nf">stacky</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
1910     <span class="k">return</span> <span class="n">thing</span><span class="o">.</span><span class="vm">__class__</span> <span class="ow">in</span> <span class="p">{</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">}</span>
1911 </pre></div>
1912 </div>
1913 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
1914 <span class="n">a</span>
1915 </pre></div>
1916 </div>
1917 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span>
1918 </pre></div>
1919 </div>
1920 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
1921 <span class="n">b</span>
1922 </pre></div>
1923 </div>
1924 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span>
1925 </pre></div>
1926 </div>
1927 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
1928     <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">&#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>
1929 </pre></div>
1930 </div>
1931 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">s1</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)}</span> <span class="o">-&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>
1932 <span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a10001</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)}</span> <span class="o">-&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>
1933 </pre></div>
1934 </div>
1935 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
1936     <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">&#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>
1937 </pre></div>
1938 </div>
1939 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">s1</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)}</span> <span class="o">-&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>
1940 <span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a10002</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)}</span> <span class="o">-&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>
1941 </pre></div>
1942 </div>
1943 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span>       <span class="p">[</span><span class="n">a1</span><span class="o">*</span><span class="p">]</span>       <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span>        <span class="p">[</span><span class="n">a1</span><span class="p">]</span>
1944
1945 <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">))</span> <span class="p">[</span><span class="n">a1</span><span class="o">*</span> <span class="n">a1</span><span class="p">]</span>    <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span>        <span class="p">[</span><span class="n">a1</span><span class="p">]</span>
1946
1947 <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span>       <span class="p">[</span><span class="n">a1</span><span class="o">*</span><span class="p">]</span>       <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a1</span><span class="o">*</span><span class="p">]</span>
1948 </pre></div>
1949 </div>
1950 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">((</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
1951
1952 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">)</span>
1953 </pre></div>
1954 </div>
1955 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span>
1956 </pre></div>
1957 </div>
1958 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">f</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]))),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
1959
1960 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">)</span>
1961 </pre></div>
1962 </div>
1963 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="n">n1</span> <span class="n">n2</span> <span class="n">n3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
1964 </pre></div>
1965 </div>
1966 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">sum_</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">):</span>
1967     <span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">&#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>
1968 </pre></div>
1969 </div>
1970 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">s1</span><span class="p">:</span> <span class="p">(</span><span class="n">n1</span><span class="p">,</span> <span class="p">(</span><span class="n">n2</span><span class="p">,</span> <span class="p">(</span><span class="n">n3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)))}</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="n">n0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)</span>
1971 <span class="p">{</span><span class="n">n1</span><span class="p">:</span> <span class="n">n10001</span><span class="p">,</span> <span class="n">s1</span><span class="p">:</span> <span class="p">(</span><span class="n">n2</span><span class="p">,</span> <span class="p">(</span><span class="n">n3</span><span class="p">,</span> <span class="n">s1</span><span class="p">))}</span> <span class="o">-&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">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>
1973 <span class="p">{</span><span class="n">n1</span><span class="p">:</span> <span class="n">n10001</span><span class="p">,</span> <span class="n">s1</span><span class="p">:</span> <span class="p">(</span><span class="n">n1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">),</span> <span class="n">n3</span><span class="p">:</span> <span class="n">n10003</span><span class="p">,</span> <span class="n">n2</span><span class="p">:</span> <span class="n">n10002</span><span class="p">}</span> <span class="o">-&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 </pre></div>
1975 </div>
1976 </div>
1977 <div class="section" id="compose-version-3">
1978 <h4><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 3<a class="headerlink" href="#compose-version-3" title="Permalink to this headline">¶</a></h4>
1979 <p>This function has to be modified to yield multiple results.</p>
1980 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
1981     <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
1982     <span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
1983     <span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
1984         <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#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>
1985     <span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">s</span><span class="p">:</span>
1986         <span class="k">yield</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">))</span>
1987 </pre></div>
1988 </div>
1989 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
1990     <span class="k">for</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">product</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
1991         <span class="k">try</span><span class="p">:</span>
1992             <span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
1993                 <span class="k">yield</span> <span class="n">result</span>
1994         <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
1995             <span class="k">pass</span>
1996
1997
1998 <span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
1999     <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
2000     <span class="k">for</span> <span class="n">fg</span> <span class="ow">in</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
2001         <span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
2002 </pre></div>
2003 </div>
2004 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
2005     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
2006 </pre></div>
2007 </div>
2008 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">f1</span> <span class="o">--</span> <span class="n">f2</span><span class="p">)</span>
2009 <span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
2010 </pre></div>
2011 </div>
2012 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
2013     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
2014 </pre></div>
2015 </div>
2016 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">n1</span><span class="p">)</span>
2017 </pre></div>
2018 </div>
2019 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">cons</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
2020     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
2021 </pre></div>
2022 </div>
2023 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n1</span><span class="p">)</span>
2024 <span class="p">(</span><span class="n">n1</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
2025 </pre></div>
2026 </div>
2027 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">(((</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
2028 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">cons</span><span class="p">),</span>
2029 <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">),</span>
2030
2031 <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">cons</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
2032     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
2033 </pre></div>
2034 </div>
2035 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">([</span><span class="n">n1</span> <span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span> <span class="p">(</span><span class="n">n1</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
2036 </pre></div>
2037 </div>
2038 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])))</span>
2039 <span class="n">a</span>
2040 </pre></div>
2041 </div>
2042 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)))</span>
2043 </pre></div>
2044 </div>
2045 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
2046 <span class="n">b</span>
2047 </pre></div>
2048 </div>
2049 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s2</span><span class="p">))</span>
2050 </pre></div>
2051 </div>
2052 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
2053     <span class="nb">print</span> <span class="n">result</span>
2054 </pre></div>
2055 </div>
2056 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="n">s1</span><span class="p">,</span> <span class="n">a2</span><span class="p">:</span> <span class="n">a3</span><span class="p">}</span>
2057 <span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">a2</span><span class="p">:</span> <span class="n">a10003</span><span class="p">}</span>
2058 </pre></div>
2059 </div>
2060 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
2061     <span class="nb">print</span> <span class="n">result</span>
2062 </pre></div>
2063 </div>
2064 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">s2</span><span class="p">:</span> <span class="n">s1</span><span class="p">,</span> <span class="n">a2</span><span class="p">:</span> <span class="n">a3</span><span class="p">,</span> <span class="n">a4</span><span class="p">:</span> <span class="n">a1</span><span class="p">}</span>
2065 <span class="p">{</span><span class="n">s2</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">a2</span><span class="p">:</span> <span class="n">a10004</span><span class="p">,</span> <span class="n">a4</span><span class="p">:</span> <span class="n">a1</span><span class="p">}</span>
2066 </pre></div>
2067 </div>
2068 </div>
2069 </div>
2070 </div>
2071 <div class="section" id="part-vii-typing-combinators">
2072 <h2>Part VII: Typing Combinators<a class="headerlink" href="#part-vii-typing-combinators" title="Permalink to this headline">¶</a></h2>
2073 <p>In order to compute the stack effect of combinators you kinda have to
2074 have the quoted programs they expect available. In the most general
2075 case, the <code class="docutils literal notranslate"><span class="pre">i</span></code> combinator, you can’t say anything about its stack
2076 effect other than it expects one quote:</p>
2077 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">i</span> <span class="p">(</span><span class="o">...</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="o">...</span> <span class="o">.</span><span class="mf">1.</span><span class="p">)</span>
2078 </pre></div>
2079 </div>
2080 <p>Or</p>
2081 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">i</span> <span class="p">(</span><span class="o">...</span> <span class="p">[</span><span class="n">A</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="o">...</span> <span class="n">A</span><span class="o">*</span><span class="p">)</span>
2082 </pre></div>
2083 </div>
2084 <p>Consider the type of:</p>
2085 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">cons</span><span class="p">]</span> <span class="n">dip</span>
2086 </pre></div>
2087 </div>
2088 <p>Obviously it would be:</p>
2089 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">..</span><span class="mi">1</span><span class="p">]</span> <span class="n">a2</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">..</span><span class="mi">1</span><span class="p">]</span> <span class="n">a2</span><span class="p">)</span>
2090 </pre></div>
2091 </div>
2092 <p><code class="docutils literal notranslate"><span class="pre">dip</span></code> itself could have:</p>
2093 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>(a1 [..1] -- ... then what?
2094 </pre></div>
2095 </div>
2096 <p>Without any information about the contents of the quote we can’t say
2097 much about the result.</p>
2098 <div class="section" id="hybrid-inferencer-interpreter">
2099 <h3>Hybrid Inferencer/Interpreter<a class="headerlink" href="#hybrid-inferencer-interpreter" title="Permalink to this headline">¶</a></h3>
2100 <p>I think there’s a way forward. If we convert our list (of terms we are
2101 composing) into a stack structure we can use it as a <em>Joy expression</em>,
2102 then we can treat the <em>output half</em> of a function’s stack effect comment
2103 as a Joy interpreter stack, and just execute combinators directly. We
2104 can hybridize the compostition function with an interpreter to evaluate
2105 combinators, compose non-combinator functions, and put type variables on
2106 the stack. For combinators like <code class="docutils literal notranslate"><span class="pre">branch</span></code> that can have more than one
2107 stack effect we have to “split universes” again and return both.</p>
2108 <div class="section" id="joy-types-for-functions">
2109 <h4>Joy Types for Functions<a class="headerlink" href="#joy-types-for-functions" title="Permalink to this headline">¶</a></h4>
2110 <p>We need a type variable for Joy functions that can go in our expressions
2111 and be used by the hybrid inferencer/interpreter. They have to store a
2112 name and a list of stack effects.</p>
2113 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">FunctionJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
2114
2115     <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
2116         <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
2117         <span class="bp">self</span><span class="o">.</span><span class="n">stack_effects</span> <span class="o">=</span> <span class="n">sec</span>
2118         <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
2119
2120     <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
2121         <span class="k">return</span> <span class="bp">self</span>
2122     <span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
2123
2124     <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
2125         <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
2126 </pre></div>
2127 </div>
2128 </div>
2129 <div class="section" id="specialized-for-simple-functions-and-combinators">
2130 <h4>Specialized for Simple Functions and Combinators<a class="headerlink" href="#specialized-for-simple-functions-and-combinators" title="Permalink to this headline">¶</a></h4>
2131 <p>For non-combinator functions the stack effects list contains stack
2132 effect comments (represented by pairs of cons-lists as described above.)</p>
2133 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">SymbolJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
2134     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;F&#39;</span>
2135 </pre></div>
2136 </div>
2137 <p>For combinators the list contains Python functions.</p>
2138 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CombinatorJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
2139
2140     <span class="n">prefix</span> <span class="o">=</span> <span class="s1">&#39;C&#39;</span>
2141
2142     <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">,</span> <span class="n">expect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
2143         <span class="nb">super</span><span class="p">(</span><span class="n">CombinatorJoyType</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">)</span>
2144         <span class="bp">self</span><span class="o">.</span><span class="n">expect</span> <span class="o">=</span> <span class="n">expect</span>
2145
2146     <span class="k">def</span> <span class="nf">enter_guard</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
2147         <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">expect</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
2148             <span class="k">return</span> <span class="n">f</span>
2149         <span class="n">g</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">expect</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">expect</span>
2150         <span class="n">new_f</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">,</span> <span class="p">()))</span>
2151         <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">new_f</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">new_f</span><span class="p">)</span>
2152         <span class="k">return</span> <span class="n">new_f</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>
2153 </pre></div>
2154 </div>
2155 <p>For simple combinators that have only one effect (like <code class="docutils literal notranslate"><span class="pre">dip</span></code>) you only
2156 need one function and it can be the combinator itself.</p>
2157 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">joy.library</span>
2158
2159 <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>
2160 </pre></div>
2161 </div>
2162 <p>For combinators that can have more than one effect (like <code class="docutils literal notranslate"><span class="pre">branch</span></code>) you
2163 have to write functions that each implement the action of one of the
2164 effects.</p>
2165 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">branch_true</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
2166     <span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
2167     <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
2168
2169 <span class="k">def</span> <span class="nf">branch_false</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
2170     <span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
2171     <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
2172
2173 <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>
2174 </pre></div>
2175 </div>
2176 <p>You can also provide an optional stack effect, input-side only, that
2177 will then be used as an identity function (that accepts and returns
2178 stacks that match the “guard” stack effect) which will be used to guard
2179 against type mismatches going into the evaluation of the combinator.</p>
2180 </div>
2181 <div class="section" id="infer">
2182 <h4><code class="docutils literal notranslate"><span class="pre">infer()</span></code><a class="headerlink" href="#infer" title="Permalink to this headline">¶</a></h4>
2183 <p>With those in place, we can define a function that accepts a sequence of
2184 Joy type variables, including ones representing functions (not just
2185 values), and attempts to grind out all the possible stack effects of
2186 that expression.</p>
2187 <p>One tricky thing is that type variables <em>in the expression</em> have to be
2188 updated along with the stack effects after doing unification or we risk
2189 losing useful information. This was a straightforward, if awkward,
2190 modification to the call structure of <code class="docutils literal notranslate"><span class="pre">meta_compose()</span></code> et. al.</p>
2191 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ID</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>  <span class="c1"># Identity function.</span>
2192
2193
2194 <span class="k">def</span> <span class="nf">infer</span><span class="p">(</span><span class="o">*</span><span class="n">expression</span><span class="p">):</span>
2195     <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">_infer</span><span class="p">(</span><span class="n">list_to_stack</span><span class="p">(</span><span class="n">expression</span><span class="p">))))</span>
2196
2197
2198 <span class="k">def</span> <span class="nf">_infer</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">F</span><span class="o">=</span><span class="n">ID</span><span class="p">):</span>
2199     <span class="n">_log_it</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
2200     <span class="k">if</span> <span class="ow">not</span> <span class="n">e</span><span class="p">:</span>
2201         <span class="k">return</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span>
2202
2203     <span class="n">n</span><span class="p">,</span> <span class="n">e</span> <span class="o">=</span> <span class="n">e</span>
2204
2205     <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">SymbolJoyType</span><span class="p">):</span>
2206         <span class="n">eFG</span> <span class="o">=</span> <span class="n">meta_compose</span><span class="p">([</span><span class="n">F</span><span class="p">],</span> <span class="n">n</span><span class="o">.</span><span class="n">stack_effects</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span>
2207         <span class="n">res</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">_infer</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">Fn</span><span class="p">)</span> <span class="k">for</span> <span class="n">e</span><span class="p">,</span> <span class="n">Fn</span> <span class="ow">in</span> <span class="n">eFG</span><span class="p">)</span>
2208
2209     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">CombinatorJoyType</span><span class="p">):</span>
2210         <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">n</span><span class="o">.</span><span class="n">enter_guard</span><span class="p">(</span><span class="n">F</span><span class="p">)</span>
2211         <span class="n">res</span> <span class="o">=</span> <span class="n">flatten</span><span class="p">(</span><span class="n">_interpret</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">n</span><span class="o">.</span><span class="n">stack_effects</span><span class="p">)</span>
2212
2213     <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">Symbol</span><span class="p">):</span>
2214         <span class="k">assert</span> <span class="n">n</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">FUNCTIONS</span><span class="p">,</span> <span class="nb">repr</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
2215         <span class="n">func</span> <span class="o">=</span> <span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">_dictionary</span><span class="p">[</span><span class="n">n</span><span class="p">]</span>
2216         <span class="n">res</span> <span class="o">=</span> <span class="n">_interpret</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">e</span><span class="p">)</span>
2217
2218     <span class="k">else</span><span class="p">:</span>
2219         <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">F</span>
2220         <span class="n">res</span> <span class="o">=</span> <span class="n">_infer</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">fo</span><span class="p">)))</span>
2221
2222     <span class="k">return</span> <span class="n">res</span>
2223
2224
2225 <span class="k">def</span> <span class="nf">_interpret</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">,</span> <span class="n">e</span><span class="p">):</span>
2226     <span class="n">new_fo</span><span class="p">,</span> <span class="n">ee</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">fo</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="p">{})</span>
2227     <span class="n">ee</span> <span class="o">=</span> <span class="n">update</span><span class="p">(</span><span class="n">FUNCTIONS</span><span class="p">,</span> <span class="n">ee</span><span class="p">)</span>  <span class="c1"># Fix Symbols.</span>
2228     <span class="n">new_F</span> <span class="o">=</span> <span class="n">fi</span><span class="p">,</span> <span class="n">new_fo</span>
2229     <span class="k">return</span> <span class="n">_infer</span><span class="p">(</span><span class="n">ee</span><span class="p">,</span> <span class="n">new_F</span><span class="p">)</span>
2230
2231
2232 <span class="k">def</span> <span class="nf">_log_it</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">F</span><span class="p">):</span>
2233     <span class="n">_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
2234         <span class="sa">u</span><span class="s1">&#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>
2235         <span class="nb">len</span><span class="p">(</span><span class="n">inspect_stack</span><span class="p">()),</span>
2236         <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">),</span>
2237         <span class="n">expression_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">),</span>
2238         <span class="p">)</span>
2239 </pre></div>
2240 </div>
2241 </div>
2242 <div class="section" id="work-in-progress">
2243 <h4>Work in Progress<a class="headerlink" href="#work-in-progress" title="Permalink to this headline">¶</a></h4>
2244 <p>And that brings us to current Work-In-Progress. The mixed-mode
2245 inferencer/interpreter <code class="docutils literal notranslate"><span class="pre">infer()</span></code> function seems to work well. There
2246 are details I should document, and the rest of the code in the
2247 “polytypes” module (FIXME link to its docs here!) should be explained…
2248 There is cruft to convert the definitions in <code class="docutils literal notranslate"><span class="pre">DEFS</span></code> to the new
2249 <code class="docutils literal notranslate"><span class="pre">SymbolJoyType</span></code> objects, and some combinators. Here is an example of
2250 output from the current code :</p>
2251 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span>  <span class="c1"># (Don&#39;t try to run this cell!  It&#39;s not going to work.  This is &quot;read only&quot; code heh..)</span>
2252
2253 <span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="nb">format</span><span class="o">=</span><span class="s1">&#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>
2254
2255 <span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">FUNCTIONS</span><span class="p">)</span>
2256
2257 <span class="n">h</span> <span class="o">=</span> <span class="n">infer</span><span class="p">((</span><span class="n">pred</span><span class="p">,</span> <span class="n">s2</span><span class="p">),</span> <span class="p">(</span><span class="n">mul</span><span class="p">,</span> <span class="n">s3</span><span class="p">),</span> <span class="p">(</span><span class="n">div</span><span class="p">,</span> <span class="n">s4</span><span class="p">),</span> <span class="p">(</span><span class="n">nullary</span><span class="p">,</span> <span class="p">(</span><span class="nb">bool</span><span class="p">,</span> <span class="n">s5</span><span class="p">)),</span> <span class="n">dipd</span><span class="p">,</span> <span class="n">branch</span><span class="p">)</span>
2258
2259 <span class="nb">print</span> <span class="s1">&#39;-&#39;</span> <span class="o">*</span> <span class="mi">40</span>
2260
2261 <span class="k">for</span> <span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="ow">in</span> <span class="n">h</span><span class="p">:</span>
2262     <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
2263 </pre></div>
2264 </div>
2265 <p>The numbers at the start of the lines are the current depth of the
2266 Python call stack. They’re followed by the current computed stack effect
2267 (initialized to <code class="docutils literal notranslate"><span class="pre">ID</span></code>) then the pending expression (the inference of
2268 the stack effect of which is the whole object of the current example.)</p>
2269 <p>In this example we are implementing (and inferring) <code class="docutils literal notranslate"><span class="pre">ifte</span></code> as
2270 <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
2271 implementation in action.</p>
2272 <div class="highlight-default notranslate"><div class="highlight"><pre><span></span>  7 (--) ∘ [pred] [mul] [div] [nullary bool] dipd branch
2273   8 (-- [pred ...2]) ∘ [mul] [div] [nullary bool] dipd branch
2274   9 (-- [pred ...2] [mul ...3]) ∘ [div] [nullary bool] dipd branch
2275  10 (-- [pred ...2] [mul ...3] [div ...4]) ∘ [nullary bool] dipd branch
2276  11 (-- [pred ...2] [mul ...3] [div ...4] [nullary bool ...5]) ∘ dipd branch
2277  15 (-- [pred ...5]) ∘ nullary bool [mul] [div] branch
2278  19 (-- [pred ...2]) ∘ [stack] dinfrirst bool [mul] [div] branch
2279  20 (-- [pred ...2] [stack ]) ∘ dinfrirst bool [mul] [div] branch
2280  22 (-- [pred ...2] [stack ]) ∘ dip infra first bool [mul] [div] branch
2281  26 (--) ∘ stack [pred] infra first bool [mul] [div] branch
2282  29 (... -- ... [...]) ∘ [pred] infra first bool [mul] [div] branch
2283  30 (... -- ... [...] [pred ...1]) ∘ infra first bool [mul] [div] branch
2284  34 (--) ∘ pred s1 swaack first bool [mul] [div] branch
2285  37 (n1 -- n2) ∘ [n1] swaack first bool [mul] [div] branch
2286  38 (... n1 -- ... n2 [n1 ...]) ∘ swaack first bool [mul] [div] branch
2287  41 (... n1 -- ... n1 [n2 ...]) ∘ first bool [mul] [div] branch
2288  44 (n1 -- n1 n2) ∘ bool [mul] [div] branch
2289  47 (n1 -- n1 b1) ∘ [mul] [div] branch
2290  48 (n1 -- n1 b1 [mul ...1]) ∘ [div] branch
2291  49 (n1 -- n1 b1 [mul ...1] [div ...2]) ∘ branch
2292  53 (n1 -- n1) ∘ div
2293  56 (f2 f1 -- f3) ∘
2294  56 (i1 f1 -- f2) ∘
2295  56 (f1 i1 -- f2) ∘
2296  56 (i2 i1 -- f1) ∘
2297  53 (n1 -- n1) ∘ mul
2298  56 (f2 f1 -- f3) ∘
2299  56 (i1 f1 -- f2) ∘
2300  56 (f1 i1 -- f2) ∘
2301  56 (i2 i1 -- i3) ∘
2302 ----------------------------------------
2303 (f2 f1 -- f3)
2304 (i1 f1 -- f2)
2305 (f1 i1 -- f2)
2306 (i2 i1 -- f1)
2307 (i2 i1 -- i3)
2308 </pre></div>
2309 </div>
2310 </div>
2311 </div>
2312 </div>
2313 <div class="section" id="conclusion">
2314 <h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this headline">¶</a></h2>
2315 <p>We built a simple type inferencer, and a kind of crude “compiler” for a
2316 subset of Joy functions. Then we built a more powerful inferencer that
2317 actually does some evaluation and explores branching code paths</p>
2318 <p>Work remains to be done:</p>
2319 <ul class="simple">
2320 <li>the rest of the library has to be covered</li>
2321 <li>figure out how to deal with <code class="docutils literal notranslate"><span class="pre">loop</span></code> and <code class="docutils literal notranslate"><span class="pre">genrec</span></code>, etc..</li>
2322 <li>extend the types to check values (see the appendix)</li>
2323 <li>other kinds of “higher order” type variables, OR, AND, etc..</li>
2324 <li>maybe rewrite in Prolog for great good?</li>
2325 <li>definitions</li>
2326 <li>don’t permit composition of functions that don’t compose</li>
2327 <li>auto-compile compilable functions</li>
2328 <li>Compiling more than just the Yin functions.</li>
2329 <li>getting better visibility (than Python debugger.)</li>
2330 <li>DOOOOCS!!!! Lots of docs!</li>
2331 <li>docstrings all around</li>
2332 <li>improve this notebook (it kinda falls apart at the end narratively. I
2333 went off and just started writing code to see if it would work. It
2334 does, but now I have to come back and describe here what I did.</li>
2335 </ul>
2336 </div>
2337 <div class="section" id="appendix-joy-in-the-logical-paradigm">
2338 <h2>Appendix: Joy in the Logical Paradigm<a class="headerlink" href="#appendix-joy-in-the-logical-paradigm" title="Permalink to this headline">¶</a></h2>
2339 <p>For <em>type checking</em> to work the type label classes have to be modified
2340 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>
2341 is <code class="docutils literal notranslate"><span class="pre">int</span></code>. If you do that you can take advantage of the <em>logical
2342 relational</em> nature of the stack effect comments to “compute in reverse”
2343 as it were. There’s a working demo of this at the end of the
2344 <code class="docutils literal notranslate"><span class="pre">polytypes</span></code> module. But if you’re interested in all that you should
2345 just use Prolog!</p>
2346 <p>Anyhow, type <em>checking</em> is a few easy steps away.</p>
2347 <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_ge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
2348     <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>
2349             <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>
2350             <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>
2351
2352 <span class="n">AnyJoyType</span><span class="o">.</span><span class="fm">__ge__</span> <span class="o">=</span> <span class="n">_ge</span>
2353 <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>
2354 <span class="n">StackJoyType</span><span class="o">.</span><span class="n">accept</span> <span class="o">=</span> <span class="nb">tuple</span>
2355 </pre></div>
2356 </div>
2357 </div>
2358 </div>
2359
2360
2361           </div>
2362         </div>
2363       </div>
2364       <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
2365         <div class="sphinxsidebarwrapper">
2366   <h3><a href="../index.html">Table Of Contents</a></h3>
2367   <ul>
2368 <li><a class="reference internal" href="#">The Blissful Elegance of Typing Joy</a><ul>
2369 <li><a class="reference internal" href="#part-i-poial-s-rules">Part I: Pöial’s Rules</a><ul>
2370 <li><a class="reference internal" href="#first-rule">First Rule</a></li>
2371 <li><a class="reference internal" href="#second-rule">Second Rule</a></li>
2372 <li><a class="reference internal" href="#third-rule">Third Rule</a></li>
2373 <li><a class="reference internal" href="#stack-effect-comments">Stack Effect Comments</a></li>
2374 <li><a class="reference internal" href="#pop-swap"><code class="docutils literal notranslate"><span class="pre">pop</span> <span class="pre">swap</span></code></a></li>
2375 <li><a class="reference internal" href="#popswap-roll"><code class="docutils literal notranslate"><span class="pre">pop∘swap</span> <span class="pre">roll&lt;</span></code></a></li>
2376 <li><a class="reference internal" href="#compiling-popswaproll">Compiling <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;</span></code></a></li>
2377 <li><a class="reference internal" href="#functions-on-stacks">Functions on Stacks</a></li>
2378 <li><a class="reference internal" href="#popswaproll-rest"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;</span> <span class="pre">rest</span></code></a></li>
2379 <li><a class="reference internal" href="#popswaproll-rest-rest"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest</span> <span class="pre">rest</span></code></a></li>
2380 <li><a class="reference internal" href="#popswaproll-restrest-cons"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest∘rest</span> <span class="pre">cons</span></code></a></li>
2381 <li><a class="reference internal" href="#popswaproll-restrestcons-cons"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll&lt;∘rest∘rest∘cons</span> <span class="pre">cons</span></code></a></li>
2382 </ul>
2383 </li>
2384 <li><a class="reference internal" href="#part-ii-implementation">Part II: Implementation</a><ul>
2385 <li><a class="reference internal" href="#representing-stack-effect-comments-in-python">Representing Stack Effect Comments in Python</a></li>
2386 <li><a class="reference internal" href="#compose"><code class="docutils literal notranslate"><span class="pre">compose()</span></code></a></li>
2387 <li><a class="reference internal" href="#unify"><code class="docutils literal notranslate"><span class="pre">unify()</span></code></a></li>
2388 <li><a class="reference internal" href="#update"><code class="docutils literal notranslate"><span class="pre">update()</span></code></a></li>
2389 <li><a class="reference internal" href="#relabel"><code class="docutils literal notranslate"><span class="pre">relabel()</span></code></a></li>
2390 <li><a class="reference internal" href="#delabel"><code class="docutils literal notranslate"><span class="pre">delabel()</span></code></a></li>
2391 <li><a class="reference internal" href="#c"><code class="docutils literal notranslate"><span class="pre">C()</span></code></a></li>
2392 <li><a class="reference internal" href="#stack-functions">Stack Functions</a></li>
2393 <li><a class="reference internal" href="#dealing-with-cons-and-uncons">Dealing with <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code></a><ul>
2394 <li><a class="reference internal" href="#unify-version-2"><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 2</a></li>
2395 </ul>
2396 </li>
2397 </ul>
2398 </li>
2399 <li><a class="reference internal" href="#part-iii-compiling-yin-functions">Part III: Compiling Yin Functions</a><ul>
2400 <li><a class="reference internal" href="#python-identifiers">Python Identifiers</a></li>
2401 <li><a class="reference internal" href="#doc-from-stack-effect"><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code></a></li>
2402 <li><a class="reference internal" href="#compile"><code class="docutils literal notranslate"><span class="pre">compile_()</span></code></a></li>
2403 <li><a class="reference internal" href="#compiling-library-functions">Compiling Library Functions</a></li>
2404 </ul>
2405 </li>
2406 <li><a class="reference internal" href="#part-iv-types-and-subtypes-of-arguments">Part IV: Types and Subtypes of Arguments</a><ul>
2407 <li><a class="reference internal" href="#number-type">“Number” Type</a></li>
2408 <li><a class="reference internal" href="#distinguishing-numbers">Distinguishing Numbers</a></li>
2409 <li><a class="reference internal" href="#distinguishing-types">Distinguishing Types</a></li>
2410 <li><a class="reference internal" href="#typing-sqr">Typing <code class="docutils literal notranslate"><span class="pre">sqr</span></code></a></li>
2411 <li><a class="reference internal" href="#modifying-the-inferencer">Modifying the Inferencer</a><ul>
2412 <li><a class="reference internal" href="#delabel-version-2"><code class="docutils literal notranslate"><span class="pre">delabel()</span></code> version 2</a></li>
2413 <li><a class="reference internal" href="#unify-version-3"><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 3</a></li>
2414 <li><a class="reference internal" href="#compose-dup-and-mul">Compose <code class="docutils literal notranslate"><span class="pre">dup</span></code> and <code class="docutils literal notranslate"><span class="pre">mul</span></code></a></li>
2415 <li><a class="reference internal" href="#compile-version-2"><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 2</a></li>
2416 <li><a class="reference internal" href="#compilable"><code class="docutils literal notranslate"><span class="pre">compilable()</span></code></a></li>
2417 </ul>
2418 </li>
2419 </ul>
2420 </li>
2421 <li><a class="reference internal" href="#part-v-functions-that-use-the-stack">Part V: Functions that use the Stack</a><ul>
2422 <li><a class="reference internal" href="#stackuncons"><code class="docutils literal notranslate"><span class="pre">stack∘uncons</span></code></a></li>
2423 <li><a class="reference internal" href="#stackunconsuncons"><code class="docutils literal notranslate"><span class="pre">stack∘uncons∘uncons</span></code></a><ul>
2424 <li><a class="reference internal" href="#compose-version-2"><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 2</a></li>
2425 </ul>
2426 </li>
2427 <li><a class="reference internal" href="#doc-from-stack-effect-version-2"><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code> version 2</a><ul>
2428 <li><a class="reference internal" href="#compile-version-3"><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 3</a></li>
2429 </ul>
2430 </li>
2431 </ul>
2432 </li>
2433 <li><a class="reference internal" href="#part-vi-multiple-stack-effects">Part VI: Multiple Stack Effects</a><ul>
2434 <li><a class="reference internal" href="#representing-an-unbounded-sequence-of-types">Representing an Unbounded Sequence of Types</a><ul>
2435 <li><a class="reference internal" href="#unify-version-4"><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 4</a></li>
2436 <li><a class="reference internal" href="#compose-version-3"><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 3</a></li>
2437 </ul>
2438 </li>
2439 </ul>
2440 </li>
2441 <li><a class="reference internal" href="#part-vii-typing-combinators">Part VII: Typing Combinators</a><ul>
2442 <li><a class="reference internal" href="#hybrid-inferencer-interpreter">Hybrid Inferencer/Interpreter</a><ul>
2443 <li><a class="reference internal" href="#joy-types-for-functions">Joy Types for Functions</a></li>
2444 <li><a class="reference internal" href="#specialized-for-simple-functions-and-combinators">Specialized for Simple Functions and Combinators</a></li>
2445 <li><a class="reference internal" href="#infer"><code class="docutils literal notranslate"><span class="pre">infer()</span></code></a></li>
2446 <li><a class="reference internal" href="#work-in-progress">Work in Progress</a></li>
2447 </ul>
2448 </li>
2449 </ul>
2450 </li>
2451 <li><a class="reference internal" href="#conclusion">Conclusion</a></li>
2452 <li><a class="reference internal" href="#appendix-joy-in-the-logical-paradigm">Appendix: Joy in the Logical Paradigm</a></li>
2453 </ul>
2454 </li>
2455 </ul>
2456 <div class="relations">
2457 <h3>Related Topics</h3>
2458 <ul>
2459   <li><a href="../index.html">Documentation overview</a><ul>
2460   <li><a href="index.html">Essays about Programming in Joy</a><ul>
2461       <li>Previous: <a href="Zipper.html" title="previous chapter">Traversing Datastructures with Zippers</a></li>
2462       <li>Next: <a href="TypeChecking.html" title="next chapter">Type Checking</a></li>
2463   </ul></li>
2464   </ul></li>
2465 </ul>
2466 </div>
2467   <div role="note" aria-label="source link">
2468     <h3>This Page</h3>
2469     <ul class="this-page-menu">
2470       <li><a href="../_sources/notebooks/Types.rst.txt"
2471             rel="nofollow">Show Source</a></li>
2472     </ul>
2473    </div>
2474 <div id="searchbox" style="display: none" role="search">
2475   <h3>Quick search</h3>
2476     <div class="searchformwrapper">
2477     <form class="search" action="../search.html" method="get">
2478       <input type="text" name="q" />
2479       <input type="submit" value="Go" />
2480       <input type="hidden" name="check_keywords" value="yes" />
2481       <input type="hidden" name="area" value="default" />
2482     </form>
2483     </div>
2484 </div>
2485 <script type="text/javascript">$('#searchbox').show(0);</script>
2486         </div>
2487       </div>
2488       <div class="clearer"></div>
2489     </div>
2490     <div class="footer" role="contentinfo">
2491 <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
2492 <img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
2493 </a>
2494 <br />
2495 <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>.
2496       Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
2497     </div>
2498
2499   </body>
2500 </html>