Merge pull request #1 from calroc/update-sphinx

Update sphinx
This commit is contained in:
Simon Forman 2021-11-19 20:52:09 +00:00 committed by GitHub
commit 4c1ceb4ea8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
95 changed files with 30613 additions and 5630 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: d581c6009ec2b560e43b1edcc2912d38
tags: 645f666f9bcd5a90fca523b33c5a78b7

View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
-->
<!-- Title: finite_state_machine Pages: 1 -->
<svg width="534pt" height="270pt"
viewBox="0.00 0.00 534.00 270.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 266)">
<title>finite_state_machine</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-266 530,-266 530,4 -4,4"/>
<!-- i -->
<g id="node1" class="node"><title>i</title>
<ellipse fill="none" stroke="black" cx="338" cy="-146" rx="18" ry="18"/>
<ellipse fill="none" stroke="black" cx="338" cy="-146" rx="22" ry="22"/>
<text text-anchor="middle" x="338" y="-142.3" font-family="Times,serif" font-size="14.00">i</text>
</g>
<!-- i&#45;&gt;i -->
<g id="edge17" class="edge"><title>i&#45;&gt;i</title>
<path fill="none" stroke="black" d="M330.317,-166.991C329.369,-177.087 331.93,-186 338,-186 341.889,-186 344.337,-182.342 345.346,-177.059"/>
<polygon fill="black" stroke="black" points="348.846,-177.102 345.683,-166.991 341.85,-176.868 348.846,-177.102"/>
<text text-anchor="middle" x="338" y="-189.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- j -->
<g id="node10" class="node"><title>j</title>
<ellipse fill="none" stroke="black" cx="421" cy="-136" rx="18" ry="18"/>
<text text-anchor="middle" x="421" y="-132.3" font-family="Times,serif" font-size="14.00">j</text>
</g>
<!-- i&#45;&gt;j -->
<g id="edge18" class="edge"><title>i&#45;&gt;j</title>
<path fill="none" stroke="black" d="M357.466,-135.495C363.775,-132.451 371.008,-129.536 378,-128 383.213,-126.855 388.811,-126.984 394.167,-127.763"/>
<polygon fill="black" stroke="black" points="393.487,-131.197 404.002,-129.894 394.97,-124.355 393.487,-131.197"/>
<text text-anchor="middle" x="381.5" y="-131.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- h -->
<g id="node2" class="node"><title>h</title>
<ellipse fill="none" stroke="black" cx="504" cy="-85" rx="18" ry="18"/>
<ellipse fill="none" stroke="black" cx="504" cy="-85" rx="22" ry="22"/>
<text text-anchor="middle" x="504" y="-81.3" font-family="Times,serif" font-size="14.00">h</text>
</g>
<!-- h&#45;&gt;i -->
<g id="edge15" class="edge"><title>h&#45;&gt;i</title>
<path fill="none" stroke="black" d="M481.868,-83.4025C461.033,-82.62 428.676,-83.5645 403,-94 387.267,-100.394 372.373,-112.028 360.918,-122.673"/>
<polygon fill="black" stroke="black" points="358.306,-120.33 353.569,-129.807 363.182,-125.353 358.306,-120.33"/>
<text text-anchor="middle" x="421" y="-97.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- h&#45;&gt;h -->
<g id="edge16" class="edge"><title>h&#45;&gt;h</title>
<path fill="none" stroke="black" d="M496.317,-105.991C495.369,-116.087 497.93,-125 504,-125 507.889,-125 510.337,-121.342 511.346,-116.059"/>
<polygon fill="black" stroke="black" points="514.846,-116.102 511.683,-105.991 507.85,-115.868 514.846,-116.102"/>
<text text-anchor="middle" x="504" y="-128.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- a -->
<g id="node3" class="node"><title>a</title>
<ellipse fill="none" stroke="black" cx="18" cy="-128" rx="18" ry="18"/>
<text text-anchor="middle" x="18" y="-124.3" font-family="Times,serif" font-size="14.00">a</text>
</g>
<!-- b -->
<g id="node4" class="node"><title>b</title>
<ellipse fill="none" stroke="black" cx="255" cy="-113" rx="18" ry="18"/>
<text text-anchor="middle" x="255" y="-109.3" font-family="Times,serif" font-size="14.00">b</text>
</g>
<!-- a&#45;&gt;b -->
<g id="edge1" class="edge"><title>a&#45;&gt;b</title>
<path fill="none" stroke="black" d="M36.2801,-126.897C76.7816,-124.312 178.091,-117.845 226.89,-114.73"/>
<polygon fill="black" stroke="black" points="227.255,-118.214 237.011,-114.084 226.809,-111.229 227.255,-118.214"/>
<text text-anchor="middle" x="136.5" y="-123.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- c -->
<g id="node5" class="node"><title>c</title>
<ellipse fill="none" stroke="black" cx="97" cy="-155" rx="18" ry="18"/>
<text text-anchor="middle" x="97" y="-151.3" font-family="Times,serif" font-size="14.00">c</text>
</g>
<!-- a&#45;&gt;c -->
<g id="edge2" class="edge"><title>a&#45;&gt;c</title>
<path fill="none" stroke="black" d="M35.3297,-133.726C45.4364,-137.27 58.635,-141.898 70.1398,-145.932"/>
<polygon fill="black" stroke="black" points="69.099,-149.276 79.6938,-149.282 71.4153,-142.67 69.099,-149.276"/>
<text text-anchor="middle" x="57.5" y="-145.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- b&#45;&gt;b -->
<g id="edge3" class="edge"><title>b&#45;&gt;b</title>
<path fill="none" stroke="black" d="M248.266,-130.037C246.892,-139.858 249.137,-149 255,-149 258.665,-149 260.916,-145.429 261.753,-140.353"/>
<polygon fill="black" stroke="black" points="265.252,-140.031 261.734,-130.037 258.252,-140.044 265.252,-140.031"/>
<text text-anchor="middle" x="255" y="-152.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- d -->
<g id="node6" class="node"><title>d</title>
<ellipse fill="none" stroke="black" cx="338" cy="-79" rx="18" ry="18"/>
<text text-anchor="middle" x="338" y="-75.3" font-family="Times,serif" font-size="14.00">d</text>
</g>
<!-- b&#45;&gt;d -->
<g id="edge4" class="edge"><title>b&#45;&gt;d</title>
<path fill="none" stroke="black" d="M272.003,-106.283C283.319,-101.533 298.722,-95.0674 311.693,-89.6227"/>
<polygon fill="black" stroke="black" points="313.164,-92.801 321.03,-85.7034 310.455,-86.3466 313.164,-92.801"/>
<text text-anchor="middle" x="294.5" y="-101.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- c&#45;&gt;b -->
<g id="edge5" class="edge"><title>c&#45;&gt;b</title>
<path fill="none" stroke="black" d="M114.862,-150.653C138.269,-144.593 181.917,-133.2 219,-123 221.799,-122.23 224.721,-121.414 227.631,-120.594"/>
<polygon fill="black" stroke="black" points="228.623,-123.951 237.284,-117.849 226.708,-117.218 228.623,-123.951"/>
<text text-anchor="middle" x="176" y="-142.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- e -->
<g id="node7" class="node"><title>e</title>
<ellipse fill="none" stroke="black" cx="176" cy="-206" rx="18" ry="18"/>
<text text-anchor="middle" x="176" y="-202.3" font-family="Times,serif" font-size="14.00">e</text>
</g>
<!-- c&#45;&gt;e -->
<g id="edge6" class="edge"><title>c&#45;&gt;e</title>
<path fill="none" stroke="black" d="M112.483,-164.593C123.668,-172.001 139.356,-182.392 152.219,-190.911"/>
<polygon fill="black" stroke="black" points="150.312,-193.846 160.582,-196.45 154.177,-188.01 150.312,-193.846"/>
<text text-anchor="middle" x="136.5" y="-185.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- d&#45;&gt;b -->
<g id="edge7" class="edge"><title>d&#45;&gt;b</title>
<path fill="none" stroke="black" d="M320.205,-74.8763C311.208,-73.4911 300.131,-73.1424 291,-77 284.094,-79.9175 277.879,-84.9376 272.669,-90.3183"/>
<polygon fill="black" stroke="black" points="269.694,-88.4067 265.791,-98.2568 274.985,-92.9902 269.694,-88.4067"/>
<text text-anchor="middle" x="294.5" y="-80.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- f -->
<g id="node8" class="node"><title>f</title>
<ellipse fill="none" stroke="black" cx="176" cy="-46" rx="18" ry="18"/>
<text text-anchor="middle" x="176" y="-42.3" font-family="Times,serif" font-size="14.00">f</text>
</g>
<!-- d&#45;&gt;f -->
<g id="edge8" class="edge"><title>d&#45;&gt;f</title>
<path fill="none" stroke="black" d="M319.923,-75.478C292.098,-69.7389 236.768,-58.3271 203.708,-51.5086"/>
<polygon fill="black" stroke="black" points="204.321,-48.0614 193.82,-49.4692 202.907,-54.9171 204.321,-48.0614"/>
<text text-anchor="middle" x="255" y="-69.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- e&#45;&gt;b -->
<g id="edge9" class="edge"><title>e&#45;&gt;b</title>
<path fill="none" stroke="black" d="M190.241,-194.796C198.908,-187.136 210.212,-176.503 219,-166 226.507,-157.028 233.803,-146.389 239.774,-137.007"/>
<polygon fill="black" stroke="black" points="242.759,-138.834 245.056,-128.491 236.81,-135.144 242.759,-138.834"/>
<text text-anchor="middle" x="215.5" y="-176.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- g -->
<g id="node9" class="node"><title>g</title>
<ellipse fill="none" stroke="black" cx="255" cy="-211" rx="18" ry="18"/>
<text text-anchor="middle" x="255" y="-207.3" font-family="Times,serif" font-size="14.00">g</text>
</g>
<!-- e&#45;&gt;g -->
<g id="edge10" class="edge"><title>e&#45;&gt;g</title>
<path fill="none" stroke="black" d="M194.089,-207.11C203.659,-207.731 215.817,-208.521 226.677,-209.226"/>
<polygon fill="black" stroke="black" points="226.753,-212.738 236.959,-209.893 227.207,-205.753 226.753,-212.738"/>
<text text-anchor="middle" x="215.5" y="-211.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- f&#45;&gt;h -->
<g id="edge12" class="edge"><title>f&#45;&gt;h</title>
<path fill="none" stroke="black" d="M189.02,-33.1864C203.151,-19.5754 227.995,-0 254,-0 254,-0 254,-0 422,-0 453.632,-0 476.677,-31.2311 489.924,-55.8314"/>
<polygon fill="black" stroke="black" points="486.862,-57.5325 494.518,-64.8562 493.1,-54.3566 486.862,-57.5325"/>
<text text-anchor="middle" x="338" y="-3.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- f&#45;&gt;b -->
<g id="edge11" class="edge"><title>f&#45;&gt;b</title>
<path fill="none" stroke="black" d="M190.834,-56.7689C199.13,-63.3319 209.817,-71.9742 219,-80 224.034,-84.4001 229.343,-89.2757 234.262,-93.899"/>
<polygon fill="black" stroke="black" points="231.917,-96.4985 241.576,-100.852 236.74,-91.4252 231.917,-96.4985"/>
<text text-anchor="middle" x="215.5" y="-83.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- g&#45;&gt;i -->
<g id="edge13" class="edge"><title>g&#45;&gt;i</title>
<path fill="none" stroke="black" d="M269.741,-199.974C281.437,-190.587 298.524,-176.876 312.548,-165.622"/>
<polygon fill="black" stroke="black" points="314.778,-168.32 320.387,-159.331 310.397,-162.86 314.778,-168.32"/>
<text text-anchor="middle" x="294.5" y="-185.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- g&#45;&gt;g -->
<g id="edge14" class="edge"><title>g&#45;&gt;g</title>
<path fill="none" stroke="black" d="M248.266,-228.037C246.892,-237.858 249.137,-247 255,-247 258.665,-247 260.916,-243.429 261.753,-238.353"/>
<polygon fill="black" stroke="black" points="265.252,-238.031 261.734,-228.037 258.252,-238.044 265.252,-238.031"/>
<text text-anchor="middle" x="255" y="-250.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
<!-- j&#45;&gt;i -->
<g id="edge19" class="edge"><title>j&#45;&gt;i</title>
<path fill="none" stroke="black" d="M403.34,-139.8C397.561,-140.993 391.021,-142.205 385,-143 380.321,-143.618 375.357,-144.11 370.488,-144.502"/>
<polygon fill="black" stroke="black" points="369.864,-141.036 360.126,-145.209 370.341,-148.02 369.864,-141.036"/>
<text text-anchor="middle" x="381.5" y="-146.8" font-family="Times,serif" font-size="14.00">0</text>
</g>
<!-- j&#45;&gt;h -->
<g id="edge20" class="edge"><title>j&#45;&gt;h</title>
<path fill="none" stroke="black" d="M436.857,-126.646C447.841,-119.73 463.1,-110.122 476.194,-101.878"/>
<polygon fill="black" stroke="black" points="478.237,-104.727 484.835,-96.4375 474.507,-98.8038 478.237,-104.727"/>
<text text-anchor="middle" x="460.5" y="-116.8" font-family="Times,serif" font-size="14.00">1</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,19 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Overview: module code &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
@ -28,24 +26,48 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>All modules for which code is available</h1>
<ul><li><a href="__builtin__.html">__builtin__</a></li>
<li><a href="joy/joy.html">joy.joy</a></li>
<ul><li><a href="joy/joy.html">joy.joy</a></li>
<li><a href="joy/library.html">joy.library</a></li>
<li><a href="joy/parser.html">joy.parser</a></li>
<li><a href="joy/utils/generated_library.html">joy.utils.generated_library</a></li>
<li><a href="joy/utils/pretty_print.html">joy.utils.pretty_print</a></li>
<li><a href="joy/utils/stack.html">joy.utils.stack</a></li>
<li><a href="joy/utils/types.html">joy.utils.types</a></li>
</ul>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
@ -53,17 +75,23 @@
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -74,7 +102,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>joy.joy &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
@ -28,6 +26,8 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.joy</h1><div class="highlight"><pre>
@ -56,98 +56,162 @@
<span class="sd">match the behaviour of the original version(s) written in C.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">print_function</span>
<span class="kn">from</span> <span class="nn">builtins</span> <span class="k">import</span> <span class="nb">input</span>
<span class="kn">from</span> <span class="nn">traceback</span> <span class="k">import</span> <span class="n">print_exc</span>
<span class="kn">from</span> <span class="nn">.parser</span> <span class="k">import</span> <span class="n">text_to_expression</span><span class="p">,</span> <span class="n">ParseError</span><span class="p">,</span> <span class="n">Symbol</span>
<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="k">import</span> <span class="n">stack_to_string</span>
<span class="kn">from</span> <span class="nn">builtins</span> <span class="kn">import</span> <span class="nb">input</span>
<span class="kn">from</span> <span class="nn">traceback</span> <span class="kn">import</span> <span class="n">print_exc</span>
<span class="kn">from</span> <span class="nn">.parser</span> <span class="kn">import</span> <span class="n">text_to_expression</span><span class="p">,</span> <span class="n">ParseError</span><span class="p">,</span> <span class="n">Symbol</span>
<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="kn">import</span> <span class="n">stack_to_string</span>
<span class="kn">from</span> <span class="nn">.utils.errors</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">NotAListError</span><span class="p">,</span>
<span class="n">NotAnIntError</span><span class="p">,</span>
<span class="n">StackUnderflowError</span><span class="p">,</span>
<span class="p">)</span>
<div class="viewcode-block" id="UnknownSymbolError"><a class="viewcode-back" href="../../joy.html#joy.joy.UnknownSymbolError">[docs]</a><span class="k">class</span> <span class="nc">UnknownSymbolError</span><span class="p">(</span><span class="ne">KeyError</span><span class="p">):</span> <span class="k">pass</span></div>
<div class="viewcode-block" id="joy"><a class="viewcode-back" href="../../joy.html#joy.joy.joy">[docs]</a><span class="k">def</span> <span class="nf">joy</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">,</span> <span class="n">viewer</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Evaluate a Joy expression on a stack.</span>
<span class="sd">&#39;&#39;&#39;Evaluate a Joy expression on a stack.</span>
<span class="sd"> This function iterates through a sequence of terms which are either</span>
<span class="sd"> literals (strings, numbers, sequences of terms) or function symbols.</span>
<span class="sd"> Literals are put onto the stack and functions are looked up in the</span>
<span class="sd"> disctionary and executed.</span>
<span class="sd"> This function iterates through a sequence of terms which are either</span>
<span class="sd"> literals (strings, numbers, sequences of terms) or function symbols.</span>
<span class="sd"> Literals are put onto the stack and functions are looked up in the</span>
<span class="sd"> dictionary and executed.</span>
<span class="sd"> The viewer is a function that is called with the stack and expression</span>
<span class="sd"> on every iteration, its return value is ignored.</span>
<span class="sd"> The viewer is a function that is called with the stack and expression</span>
<span class="sd"> on every iteration, its return value is ignored.</span>
<span class="sd"> :param stack stack: The stack.</span>
<span class="sd"> :param stack expression: The expression to evaluate.</span>
<span class="sd"> :param dict dictionary: A ``dict`` mapping names to Joy functions.</span>
<span class="sd"> :param function viewer: Optional viewer function.</span>
<span class="sd"> :rtype: (stack, (), dictionary)</span>
<span class="sd"> :param stack stack: The stack.</span>
<span class="sd"> :param stack expression: The expression to evaluate.</span>
<span class="sd"> :param dict dictionary: A ``dict`` mapping names to Joy functions.</span>
<span class="sd"> :param function viewer: Optional viewer function.</span>
<span class="sd"> :rtype: (stack, (), dictionary)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">while</span> <span class="n">expression</span><span class="p">:</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">while</span> <span class="n">expression</span><span class="p">:</span>
<span class="k">if</span> <span class="n">viewer</span><span class="p">:</span> <span class="n">viewer</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="k">if</span> <span class="n">viewer</span><span class="p">:</span> <span class="n">viewer</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">term</span><span class="p">,</span> <span class="n">expression</span> <span class="o">=</span> <span class="n">expression</span>
<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">Symbol</span><span class="p">):</span>
<span class="n">term</span> <span class="o">=</span> <span class="n">dictionary</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">expression</span><span class="p">,</span> <span class="n">dictionary</span> <span class="o">=</span> <span class="n">term</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">stack</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">stack</span>
<span class="n">term</span><span class="p">,</span> <span class="n">expression</span> <span class="o">=</span> <span class="n">expression</span>
<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">Symbol</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">term</span> <span class="o">=</span> <span class="n">dictionary</span><span class="p">[</span><span class="n">term</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">UnknownSymbolError</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">expression</span><span class="p">,</span> <span class="n">dictionary</span> <span class="o">=</span> <span class="n">term</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">stack</span> <span class="o">=</span> <span class="n">term</span><span class="p">,</span> <span class="n">stack</span>
<span class="k">if</span> <span class="n">viewer</span><span class="p">:</span> <span class="n">viewer</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="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span></div>
<span class="k">if</span> <span class="n">viewer</span><span class="p">:</span> <span class="n">viewer</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="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span></div>
<div class="viewcode-block" id="run"><a class="viewcode-back" href="../../joy.html#joy.joy.run">[docs]</a><span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">,</span> <span class="n">viewer</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return the stack resulting from running the Joy code text on the stack.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return the stack resulting from running the Joy code text on the stack.</span>
<span class="sd"> :param str text: Joy code.</span>
<span class="sd"> :param stack stack: The stack.</span>
<span class="sd"> :param dict dictionary: A ``dict`` mapping names to Joy functions.</span>
<span class="sd"> :param function viewer: Optional viewer function.</span>
<span class="sd"> :rtype: (stack, (), dictionary)</span>
<span class="sd"> :param str text: Joy code.</span>
<span class="sd"> :param stack stack: The stack.</span>
<span class="sd"> :param dict dictionary: A ``dict`` mapping names to Joy functions.</span>
<span class="sd"> :param function viewer: Optional viewer function.</span>
<span class="sd"> :rtype: (stack, (), dictionary)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">expression</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<span class="k">return</span> <span class="n">joy</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">,</span> <span class="n">viewer</span><span class="p">)</span></div>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">expression</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<span class="k">return</span> <span class="n">joy</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">,</span> <span class="n">viewer</span><span class="p">)</span></div>
<div class="viewcode-block" id="repl"><a class="viewcode-back" href="../../joy.html#joy.joy.repl">[docs]</a><span class="k">def</span> <span class="nf">repl</span><span class="p">(</span><span class="n">stack</span><span class="o">=</span><span class="p">(),</span> <span class="n">dictionary</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Read-Evaluate-Print Loop</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Read-Evaluate-Print Loop</span>
<span class="sd"> Accept input and run it on the stack, loop.</span>
<span class="sd"> Accept input and run it on the stack, loop.</span>
<span class="sd"> :param stack stack: The stack.</span>
<span class="sd"> :param dict dictionary: A ``dict`` mapping names to Joy functions.</span>
<span class="sd"> :rtype: stack</span>
<span class="sd"> :param stack stack: The stack.</span>
<span class="sd"> :param dict dictionary: A ``dict`` mapping names to Joy functions.</span>
<span class="sd"> :rtype: stack</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">dictionary</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">dictionary</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="nb">print</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">stack_to_string</span><span class="p">(</span><span class="n">stack</span><span class="p">),</span> <span class="s1">&#39;&lt;-top&#39;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">text</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s1">&#39;joy? &#39;</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">EOFError</span><span class="p">,</span> <span class="ne">KeyboardInterrupt</span><span class="p">):</span>
<span class="k">break</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">stack</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">dictionary</span> <span class="o">=</span> <span class="n">run</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">print_exc</span><span class="p">()</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">print_exc</span><span class="p">()</span>
<span class="nb">print</span><span class="p">()</span>
<span class="k">return</span> <span class="n">stack</span></div>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">dictionary</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">dictionary</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="nb">print</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">stack_to_string</span><span class="p">(</span><span class="n">stack</span><span class="p">),</span> <span class="s1">&#39;&lt;-top&#39;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">text</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s1">&#39;joy? &#39;</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">EOFError</span><span class="p">,</span> <span class="ne">KeyboardInterrupt</span><span class="p">):</span>
<span class="k">break</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">stack</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">dictionary</span> <span class="o">=</span> <span class="n">run</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">print_exc</span><span class="p">()</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">print_exc</span><span class="p">()</span>
<span class="nb">print</span><span class="p">()</span>
<span class="k">return</span> <span class="n">stack</span></div>
<div class="viewcode-block" id="interp"><a class="viewcode-back" href="../../joy.html#joy.joy.interp">[docs]</a><span class="k">def</span> <span class="nf">interp</span><span class="p">(</span><span class="n">stack</span><span class="o">=</span><span class="p">(),</span> <span class="n">dictionary</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Simple REPL with no extra output, suitable for use in scripts.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">dictionary</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">dictionary</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">text</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">EOFError</span><span class="p">,</span> <span class="ne">KeyboardInterrupt</span><span class="p">):</span>
<span class="k">break</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">stack</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">dictionary</span> <span class="o">=</span> <span class="n">run</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">)</span>
<span class="k">except</span> <span class="n">UnknownSymbolError</span> <span class="k">as</span> <span class="n">sym</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Unknown:&#39;</span><span class="p">,</span> <span class="n">sym</span><span class="p">)</span>
<span class="k">except</span> <span class="n">StackUnderflowError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="c1"># &#39;Not enough values on stack.&#39;</span>
<span class="k">except</span> <span class="n">NotAnIntError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Not an integer.&#39;</span><span class="p">)</span>
<span class="k">except</span> <span class="n">NotAListError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="c1"># &#39;Not a list.&#39;</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">print_exc</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">stack_to_string</span><span class="p">(</span><span class="n">stack</span><span class="p">))</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">print_exc</span><span class="p">()</span>
<span class="k">return</span> <span class="n">stack</span></div>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../index.html">Documentation overview</a><ul>
@ -157,17 +221,23 @@
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -178,7 +248,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>joy.parser &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../_static/jquery.js"></script>
<script type="text/javascript" src="../../_static/underscore.js"></script>
<script type="text/javascript" src="../../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/doctools.js"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
@ -28,6 +26,8 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.parser</h1><div class="highlight"><pre>
@ -69,99 +69,121 @@
<span class="sd">around square brackets.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">re</span> <span class="k">import</span> <span class="n">Scanner</span>
<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="k">import</span> <span class="n">list_to_stack</span>
<span class="kn">from</span> <span class="nn">re</span> <span class="kn">import</span> <span class="n">Scanner</span>
<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="kn">import</span> <span class="n">list_to_stack</span>
<span class="c1">#TODO: explain the details of float lits and strings.</span>
<span class="n">FLOAT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;-?\d+\.\d*(e(-|\+)\d+)?&#39;</span>
<span class="n">INT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;-?\d+&#39;</span>
<span class="n">SYMBOL</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;[•\w!@$%^&amp;*()_+&lt;&gt;?|\/;:`~,.=-]+&#39;</span>
<span class="n">BRACKETS</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;\[|\]&#39;</span>
<span class="n">STRING_DOUBLE_QUOTED</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;&quot;(?:[^&quot;</span><span class="se">\\</span><span class="s1">]|</span><span class="se">\\</span><span class="s1">.)*&quot;&#39;</span>
<span class="n">STRING_SINGLE_QUOTED</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">&quot;&#39;(?:[^&#39;</span><span class="se">\\</span><span class="s2">]|</span><span class="se">\\</span><span class="s2">.)*&#39;&quot;</span>
<span class="n">BLANKS</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;\s+&#39;</span>
<span class="n">WORDS</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;[^[\]\s]+&#39;</span>
<span class="n">token_scanner</span> <span class="o">=</span> <span class="n">Scanner</span><span class="p">([</span>
<span class="p">(</span><span class="n">BRACKETS</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="n">token</span><span class="p">),</span>
<span class="p">(</span><span class="n">BLANKS</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span>
<span class="p">(</span><span class="n">WORDS</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="n">token</span><span class="p">),</span>
<span class="p">])</span>
<div class="viewcode-block" id="Symbol"><a class="viewcode-back" href="../../parser.html#joy.parser.Symbol">[docs]</a><span class="k">class</span> <span class="nc">Symbol</span><span class="p">(</span><span class="nb">str</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;A string class that represents Joy function names.&#39;&#39;&#39;</span>
<span class="fm">__repr__</span> <span class="o">=</span> <span class="nb">str</span><span class="o">.</span><span class="fm">__str__</span></div>
<span class="sd">&#39;&#39;&#39;A string class that represents Joy function names.&#39;&#39;&#39;</span>
<span class="fm">__repr__</span> <span class="o">=</span> <span class="nb">str</span><span class="o">.</span><span class="fm">__str__</span></div>
<div class="viewcode-block" id="text_to_expression"><a class="viewcode-back" href="../../parser.html#joy.parser.text_to_expression">[docs]</a><span class="k">def</span> <span class="nf">text_to_expression</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Convert a string to a Joy expression.</span>
<span class="sd">&#39;&#39;&#39;Convert a string to a Joy expression.</span>
<span class="sd"> When supplied with a string this function returns a Python datastructure</span>
<span class="sd"> that represents the Joy datastructure described by the text expression.</span>
<span class="sd"> Any unbalanced square brackets will raise a ParseError.</span>
<span class="sd"> When supplied with a string this function returns a Python datastructure</span>
<span class="sd"> that represents the Joy datastructure described by the text expression.</span>
<span class="sd"> Any unbalanced square brackets will raise a ParseError.</span>
<span class="sd"> :param str text: Text to convert.</span>
<span class="sd"> :rtype: stack</span>
<span class="sd"> :raises ParseError: if the parse fails.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">return</span> <span class="n">_parse</span><span class="p">(</span><span class="n">_tokenize</span><span class="p">(</span><span class="n">text</span><span class="p">))</span></div>
<span class="sd"> :param str text: Text to convert.</span>
<span class="sd"> :rtype: stack</span>
<span class="sd"> :raises ParseError: if the parse fails.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">return</span> <span class="n">_parse</span><span class="p">(</span><span class="n">_tokenize</span><span class="p">(</span><span class="n">text</span><span class="p">))</span></div>
<div class="viewcode-block" id="ParseError"><a class="viewcode-back" href="../../parser.html#joy.parser.ParseError">[docs]</a><span class="k">class</span> <span class="nc">ParseError</span><span class="p">(</span><span class="ne">ValueError</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Raised when there is a error while parsing text.&#39;&#39;&#39;</span></div>
<span class="sd">&#39;&#39;&#39;Raised when there is a error while parsing text.&#39;&#39;&#39;</span></div>
<span class="k">def</span> <span class="nf">_tokenize</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Convert a text into a stream of tokens.</span>
<span class="sd">&#39;&#39;&#39;Convert a text into a stream of tokens.</span>
<span class="sd"> Converts function names to Symbols.</span>
<span class="sd"> Converts function names to Symbols.</span>
<span class="sd"> Raise ParseError (with some of the failing text) if the scan fails.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">tokens</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">_scanner</span><span class="o">.</span><span class="n">scan</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rest</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span>
<span class="s1">&#39;Scan failed at position </span><span class="si">%i</span><span class="s1">, </span><span class="si">%r</span><span class="s1">&#39;</span>
<span class="o">%</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">text</span><span class="p">)</span> <span class="o">-</span> <span class="nb">len</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="mi">10</span><span class="p">])</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">tokens</span>
<span class="sd"> Raise ParseError (with some of the failing text) if the scan fails.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">tokens</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">token_scanner</span><span class="o">.</span><span class="n">scan</span><span class="p">(</span><span class="n">text</span><span class="p">)</span>
<span class="k">if</span> <span class="n">rest</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span>
<span class="s1">&#39;Scan failed at position </span><span class="si">%i</span><span class="s1">, </span><span class="si">%r</span><span class="s1">&#39;</span>
<span class="o">%</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">text</span><span class="p">)</span> <span class="o">-</span> <span class="nb">len</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="mi">10</span><span class="p">])</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">tokens</span>
<span class="k">def</span> <span class="nf">_parse</span><span class="p">(</span><span class="n">tokens</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a stack/list expression of the tokens.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">frame</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">stack</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">tok</span> <span class="ow">in</span> <span class="n">tokens</span><span class="p">:</span>
<span class="k">if</span> <span class="n">tok</span> <span class="o">==</span> <span class="s1">&#39;[&#39;</span><span class="p">:</span>
<span class="n">stack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">frame</span><span class="p">)</span>
<span class="n">frame</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">stack</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">frame</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">tok</span> <span class="o">==</span> <span class="s1">&#39;]&#39;</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">frame</span> <span class="o">=</span> <span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="s1">&#39;Extra closing bracket.&#39;</span><span class="p">)</span>
<span class="n">frame</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">list_to_stack</span><span class="p">(</span><span class="n">frame</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">frame</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">tok</span><span class="p">)</span>
<span class="k">if</span> <span class="n">stack</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="s1">&#39;Unclosed bracket.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">list_to_stack</span><span class="p">(</span><span class="n">frame</span><span class="p">)</span>
<span class="n">_scanner</span> <span class="o">=</span> <span class="n">Scanner</span><span class="p">([</span>
<span class="p">(</span><span class="n">FLOAT</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="nb">float</span><span class="p">(</span><span class="n">token</span><span class="p">)),</span>
<span class="p">(</span><span class="n">INT</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="nb">int</span><span class="p">(</span><span class="n">token</span><span class="p">)),</span>
<span class="p">(</span><span class="n">SYMBOL</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="n">Symbol</span><span class="p">(</span><span class="n">token</span><span class="p">)),</span>
<span class="p">(</span><span class="n">BRACKETS</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="n">token</span><span class="p">),</span>
<span class="p">(</span><span class="n">STRING_DOUBLE_QUOTED</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="n">token</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\\</span><span class="s1">&quot;&#39;</span><span class="p">,</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">)),</span>
<span class="p">(</span><span class="n">STRING_SINGLE_QUOTED</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">,</span> <span class="n">token</span><span class="p">:</span> <span class="n">token</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">&#39;&quot;</span><span class="p">,</span> <span class="s2">&quot;&#39;&quot;</span><span class="p">)),</span>
<span class="p">(</span><span class="n">BLANKS</span><span class="p">,</span> <span class="kc">None</span><span class="p">),</span>
<span class="p">])</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a stack/list expression of the tokens.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">frame</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">stack</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">tok</span> <span class="ow">in</span> <span class="n">tokens</span><span class="p">:</span>
<span class="k">if</span> <span class="n">tok</span> <span class="o">==</span> <span class="s1">&#39;[&#39;</span><span class="p">:</span>
<span class="n">stack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">frame</span><span class="p">)</span>
<span class="n">frame</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">elif</span> <span class="n">tok</span> <span class="o">==</span> <span class="s1">&#39;]&#39;</span><span class="p">:</span>
<span class="n">v</span> <span class="o">=</span> <span class="n">frame</span>
<span class="k">try</span><span class="p">:</span> <span class="n">frame</span> <span class="o">=</span> <span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="s1">&#39;Extra closing bracket.&#39;</span><span class="p">)</span>
<span class="n">frame</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">list_to_stack</span><span class="p">(</span><span class="n">v</span><span class="p">))</span>
<span class="k">elif</span> <span class="n">tok</span> <span class="o">==</span> <span class="s1">&#39;true&#39;</span><span class="p">:</span>
<span class="n">frame</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">tok</span> <span class="o">==</span> <span class="s1">&#39;false&#39;</span><span class="p">:</span>
<span class="n">frame</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">thing</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">tok</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="n">thing</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="n">tok</span><span class="p">)</span>
<span class="n">frame</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">thing</span><span class="p">)</span>
<span class="k">if</span> <span class="n">stack</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParseError</span><span class="p">(</span><span class="s1">&#39;Unclosed bracket.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">list_to_stack</span><span class="p">(</span><span class="n">frame</span><span class="p">)</span>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../index.html">Documentation overview</a><ul>
@ -171,17 +193,23 @@
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -192,7 +220,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -0,0 +1,519 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>joy.utils.generated_library &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css" />
<script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
<script src="../../../_static/jquery.js"></script>
<script src="../../../_static/underscore.js"></script>
<script src="../../../_static/doctools.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.utils.generated_library</h1><div class="highlight"><pre>
<span></span><span class="c1"># GENERATED FILE. DO NOT EDIT.</span>
<span class="c1"># The code that generated these functions is in the repo history</span>
<span class="c1"># at the v0.4.0 tag.</span>
<span class="kn">from</span> <span class="nn">.errors</span> <span class="kn">import</span> <span class="n">NotAListError</span><span class="p">,</span> <span class="n">StackUnderflowError</span>
<span class="k">def</span> <span class="nf">_Tree_add_Ee</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">((</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a5</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="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</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="k">def</span> <span class="nf">_Tree_delete_R0</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a2 ...1] a1 -- [a2 ...1] a2 a1 a1)</span>
<span class="sd"> &quot;&quot;&quot;</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">s2</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">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="p">((</span><span class="n">a2</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="k">def</span> <span class="nf">_Tree_delete_clear_stuff</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a3 a2 [a1 ...1] -- [...1])</span>
<span class="sd"> &quot;&quot;&quot;</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">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s2</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_Tree_get_E</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a3 a4 ...1] a2 a1 -- a4)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">((</span><span class="n">a3</span><span class="p">,</span> <span class="p">(</span><span class="n">a4</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="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span>
<div class="viewcode-block" id="ccons"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.ccons">[docs]</a><span class="k">def</span> <span class="nf">ccons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a2 a1 [...1] -- [a2 a1 ...1])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s2</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">)</span></div>
<div class="viewcode-block" id="cons"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.cons">[docs]</a><span class="k">def</span> <span class="nf">cons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a1 [...0] -- [a1 ...0])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span> <span class="n">s0</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="k">raise</span> <span class="n">StackUnderflowError</span><span class="p">(</span><span class="s1">&#39;Not enough values on stack.&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span> <span class="k">raise</span> <span class="n">NotAListError</span><span class="p">(</span><span class="s1">&#39;Not a list.&#39;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span> <span class="n">a1</span><span class="p">,</span> <span class="n">s23</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="k">raise</span> <span class="n">StackUnderflowError</span><span class="p">(</span><span class="s1">&#39;Not enough values on stack.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="n">s0</span><span class="p">),</span> <span class="n">s23</span><span class="p">)</span></div>
<div class="viewcode-block" id="dup"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.dup">[docs]</a><span class="k">def</span> <span class="nf">dup</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a1 -- a1 a1)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">))</span></div>
<div class="viewcode-block" id="dupd"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.dupd">[docs]</a><span class="k">def</span> <span class="nf">dupd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a2 a1 -- a2 a2 a1)</span>
<span class="sd"> &quot;&quot;&quot;</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">s23</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span></div>
<div class="viewcode-block" id="dupdd"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.dupdd">[docs]</a><span class="k">def</span> <span class="nf">dupdd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a3 a2 a1 -- a3 a3 a2 a1)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</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">a3</span><span class="p">,</span> <span class="n">s23</span><span class="p">))))</span></div>
<div class="viewcode-block" id="first"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.first">[docs]</a><span class="k">def</span> <span class="nf">first</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a1 ...1] -- a1)</span>
<span class="sd"> &quot;&quot;&quot;</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">s23</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">)</span></div>
<div class="viewcode-block" id="first_two"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.first_two">[docs]</a><span class="k">def</span> <span class="nf">first_two</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a1 a2 ...1] -- a1 a2)</span>
<span class="sd"> &quot;&quot;&quot;</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">s2</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">))</span></div>
<div class="viewcode-block" id="fourth"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.fourth">[docs]</a><span class="k">def</span> <span class="nf">fourth</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a1 a2 a3 a4 ...1] -- a4)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">(</span><span class="n">a4</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="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span></div>
<div class="viewcode-block" id="over"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.over">[docs]</a><span class="k">def</span> <span class="nf">over</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a2 a1 -- a2 a1 a2)</span>
<span class="sd"> &quot;&quot;&quot;</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">s23</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span></div>
<div class="viewcode-block" id="pop"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.pop">[docs]</a><span class="k">def</span> <span class="nf">pop</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a1 --)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">StackUnderflowError</span><span class="p">(</span><span class="s1">&#39;Cannot pop empty stack.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">s23</span></div>
<div class="viewcode-block" id="popd"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.popd">[docs]</a><span class="k">def</span> <span class="nf">popd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a2 a1 -- a1)</span>
<span class="sd"> &quot;&quot;&quot;</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">s23</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">)</span></div>
<div class="viewcode-block" id="popdd"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.popdd">[docs]</a><span class="k">def</span> <span class="nf">popdd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a3 a2 a1 -- a2 a1)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s23</span><span class="p">))</span></div>
<div class="viewcode-block" id="popop"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.popop">[docs]</a><span class="k">def</span> <span class="nf">popop</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a2 a1 --)</span>
<span class="sd"> &quot;&quot;&quot;</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">s23</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="n">s23</span></div>
<div class="viewcode-block" id="popopd"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.popopd">[docs]</a><span class="k">def</span> <span class="nf">popopd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a3 a2 a1 -- a1)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">)</span></div>
<div class="viewcode-block" id="popopdd"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.popopdd">[docs]</a><span class="k">def</span> <span class="nf">popopdd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a4 a3 a2 a1 -- a2 a1)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="n">s23</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s23</span><span class="p">))</span></div>
<div class="viewcode-block" id="rest"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.rest">[docs]</a><span class="k">def</span> <span class="nf">rest</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a1 ...0] -- [...0])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">s0</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">StackUnderflowError</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">NotAListError</span><span class="p">(</span><span class="s1">&#39;Not a list.&#39;</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">_</span><span class="p">,</span> <span class="n">s1</span> <span class="o">=</span> <span class="n">s0</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">StackUnderflowError</span><span class="p">(</span><span class="s1">&#39;Cannot take rest of empty list.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span></div>
<div class="viewcode-block" id="rolldown"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.rolldown">[docs]</a><span class="k">def</span> <span class="nf">rolldown</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a1 a2 a3 -- a2 a3 a1)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span></div>
<div class="viewcode-block" id="rollup"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.rollup">[docs]</a><span class="k">def</span> <span class="nf">rollup</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a1 a2 a3 -- a3 a1 a2)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span></div>
<div class="viewcode-block" id="rrest"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.rrest">[docs]</a><span class="k">def</span> <span class="nf">rrest</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a1 a2 ...1] -- [...1])</span>
<span class="sd"> &quot;&quot;&quot;</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">s2</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span></div>
<div class="viewcode-block" id="second"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.second">[docs]</a><span class="k">def</span> <span class="nf">second</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a1 a2 ...1] -- a2)</span>
<span class="sd"> &quot;&quot;&quot;</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">s2</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span></div>
<div class="viewcode-block" id="stack"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.stack">[docs]</a><span class="k">def</span> <span class="nf">stack</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (... -- ... [...])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">s0</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="n">s0</span><span class="p">)</span></div>
<div class="viewcode-block" id="stuncons"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.stuncons">[docs]</a><span class="k">def</span> <span class="nf">stuncons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (... a1 -- ... a1 a1 [...])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">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></div>
<div class="viewcode-block" id="stununcons"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.stununcons">[docs]</a><span class="k">def</span> <span class="nf">stununcons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (... a2 a1 -- ... a2 a1 a1 a2 [...])</span>
<span class="sd"> &quot;&quot;&quot;</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="o">=</span> <span class="n">stack</span>
<span class="k">return</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></div>
<div class="viewcode-block" id="swaack"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.swaack">[docs]</a><span class="k">def</span> <span class="nf">swaack</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([...1] -- [...0])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s0</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">StackUnderflowError</span><span class="p">(</span><span class="s1">&#39;Not enough values on stack.&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">NotAListError</span><span class="p">(</span><span class="s1">&#39;Not a list.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span></div>
<div class="viewcode-block" id="swap"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.swap">[docs]</a><span class="k">def</span> <span class="nf">swap</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a1 a2 -- a2 a1)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</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">s23</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">StackUnderflowError</span><span class="p">(</span><span class="s1">&#39;Not enough values on stack.&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s23</span><span class="p">))</span></div>
<div class="viewcode-block" id="swons"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.swons">[docs]</a><span class="k">def</span> <span class="nf">swons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([...1] a1 -- [a1 ...1])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</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="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">),</span> <span class="n">s2</span><span class="p">)</span></div>
<div class="viewcode-block" id="third"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.third">[docs]</a><span class="k">def</span> <span class="nf">third</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a1 a2 a3 ...1] -- a3)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">))),</span> <span class="n">s2</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span></div>
<div class="viewcode-block" id="tuck"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.tuck">[docs]</a><span class="k">def</span> <span class="nf">tuck</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a2 a1 -- a1 a2 a1)</span>
<span class="sd"> &quot;&quot;&quot;</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">s23</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">)))</span></div>
<div class="viewcode-block" id="uncons"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.uncons">[docs]</a><span class="k">def</span> <span class="nf">uncons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a1 ...0] -- a1 [...0])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="n">s0</span><span class="p">),</span> <span class="n">s23</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">))</span></div>
<div class="viewcode-block" id="unit"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.unit">[docs]</a><span class="k">def</span> <span class="nf">unit</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> (a1 -- [a1 ])</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s23</span><span class="p">)</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">()),</span> <span class="n">s23</span><span class="p">)</span></div>
<div class="viewcode-block" id="unswons"><a class="viewcode-back" href="../../../library.html#joy.utils.generated_library.unswons">[docs]</a><span class="k">def</span> <span class="nf">unswons</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> ::</span>
<span class="sd"> ([a1 ...1] -- [...1] a1)</span>
<span class="sd"> &quot;&quot;&quot;</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="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">))</span></div>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
<li><a href="../../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer" role="contentinfo">
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
<img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>
</html>

View File

@ -1,19 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>joy.utils.pretty_print &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css" />
<script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
<script src="../../../_static/jquery.js"></script>
<script src="../../../_static/underscore.js"></script>
<script src="../../../_static/doctools.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
@ -28,6 +26,8 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.utils.pretty_print</h1><div class="highlight"><pre>
@ -71,100 +71,121 @@
<span class="sd">&#39;&#39;&#39;</span>
<span class="c1"># (Kinda clunky and hacky. This should be swapped out in favor of much</span>
<span class="c1"># smarter stuff.)</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">print_function</span>
<span class="kn">from</span> <span class="nn">builtins</span> <span class="k">import</span> <span class="nb">object</span>
<span class="kn">from</span> <span class="nn">traceback</span> <span class="k">import</span> <span class="n">print_exc</span>
<span class="kn">from</span> <span class="nn">.stack</span> <span class="k">import</span> <span class="n">expression_to_string</span><span class="p">,</span> <span class="n">stack_to_string</span>
<span class="kn">from</span> <span class="nn">..joy</span> <span class="k">import</span> <span class="n">joy</span>
<span class="kn">from</span> <span class="nn">..library</span> <span class="k">import</span> <span class="n">inscribe</span><span class="p">,</span> <span class="n">FunctionWrapper</span>
<span class="kn">from</span> <span class="nn">traceback</span> <span class="kn">import</span> <span class="n">print_exc</span>
<span class="kn">from</span> <span class="nn">.stack</span> <span class="kn">import</span> <span class="n">expression_to_string</span><span class="p">,</span> <span class="n">stack_to_string</span>
<span class="kn">from</span> <span class="nn">..joy</span> <span class="kn">import</span> <span class="n">joy</span>
<span class="kn">from</span> <span class="nn">..library</span> <span class="kn">import</span> <span class="n">FunctionWrapper</span>
<div class="viewcode-block" id="trace"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.trace">[docs]</a><span class="nd">@inscribe</span>
<span class="nd">@FunctionWrapper</span>
<div class="viewcode-block" id="trace"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.trace">[docs]</a><span class="nd">@FunctionWrapper</span>
<span class="k">def</span> <span class="nf">trace</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Evaluate a Joy expression on a stack and print a trace.</span>
<span class="sd">&#39;&#39;&#39;Evaluate a Joy expression on a stack and print a trace.</span>
<span class="sd"> This function is just like the `i` combinator but it also prints a</span>
<span class="sd"> trace of the evaluation</span>
<span class="sd"> This function is just like the `i` combinator but it also prints a</span>
<span class="sd"> trace of the evaluation</span>
<span class="sd"> :param stack stack: The stack.</span>
<span class="sd"> :param stack expression: The expression to evaluate.</span>
<span class="sd"> :param dict dictionary: A ``dict`` mapping names to Joy functions.</span>
<span class="sd"> :rtype: (stack, (), dictionary)</span>
<span class="sd"> :param stack stack: The stack.</span>
<span class="sd"> :param stack expression: The expression to evaluate.</span>
<span class="sd"> :param dict dictionary: A ``dict`` mapping names to Joy functions.</span>
<span class="sd"> :rtype: (stack, (), dictionary)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">tp</span> <span class="o">=</span> <span class="n">TracePrinter</span><span class="p">()</span>
<span class="n">quote</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">s</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="n">joy</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">quote</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">,</span> <span class="n">tp</span><span class="o">.</span><span class="n">viewer</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">tp</span><span class="o">.</span><span class="n">print_</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;-&#39;</span> <span class="o">*</span> <span class="mi">73</span><span class="p">)</span>
<span class="k">raise</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">tp</span><span class="o">.</span><span class="n">print_</span><span class="p">()</span>
<span class="k">return</span> <span class="n">s</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">d</span></div>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">tp</span> <span class="o">=</span> <span class="n">TracePrinter</span><span class="p">()</span>
<span class="n">quote</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">s</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">d</span> <span class="o">=</span> <span class="n">joy</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">quote</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">,</span> <span class="n">tp</span><span class="o">.</span><span class="n">viewer</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">tp</span><span class="o">.</span><span class="n">print_</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;-&#39;</span> <span class="o">*</span> <span class="mi">73</span><span class="p">)</span>
<span class="k">raise</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">tp</span><span class="o">.</span><span class="n">print_</span><span class="p">()</span>
<span class="k">return</span> <span class="n">s</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">d</span></div>
<div class="viewcode-block" id="TracePrinter"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.TracePrinter">[docs]</a><span class="k">class</span> <span class="nc">TracePrinter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> This is what does the formatting. You instantiate it and pass the ``viewer()``</span>
<span class="sd"> method to the :py:func:`joy.joy.joy` function, then print it to see the</span>
<span class="sd"> trace.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> This is what does the formatting. You instantiate it and pass the ``viewer()``</span>
<span class="sd"> method to the :py:func:`joy.joy.joy` function, then print it to see the</span>
<span class="sd"> trace.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">history</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">history</span> <span class="o">=</span> <span class="p">[]</span>
<div class="viewcode-block" id="TracePrinter.viewer"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.TracePrinter.viewer">[docs]</a> <span class="k">def</span> <span class="nf">viewer</span><span class="p">(</span><span class="bp">self</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="sd">&#39;&#39;&#39;</span>
<span class="sd"> Record the current stack and expression in the TracePrinter&#39;s history.</span>
<span class="sd"> Pass this method as the ``viewer`` argument to the :py:func:`joy.joy.joy` function.</span>
<div class="viewcode-block" id="TracePrinter.viewer"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.TracePrinter.viewer">[docs]</a> <span class="k">def</span> <span class="nf">viewer</span><span class="p">(</span><span class="bp">self</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="sd">&#39;&#39;&#39;</span>
<span class="sd"> Record the current stack and expression in the TracePrinter&#39;s history.</span>
<span class="sd"> Pass this method as the ``viewer`` argument to the :py:func:`joy.joy.joy` function.</span>
<span class="sd"> :param stack quote: A stack.</span>
<span class="sd"> :param stack expression: A stack.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">))</span></div>
<span class="sd"> :param stack quote: A stack.</span>
<span class="sd"> :param stack expression: A stack.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">))</span></div>
<span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">go</span><span class="p">())</span>
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">go</span><span class="p">())</span>
<div class="viewcode-block" id="TracePrinter.go"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.TracePrinter.go">[docs]</a> <span class="k">def</span> <span class="nf">go</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a list of strings, one for each entry in the history, prefixed</span>
<span class="sd"> with enough spaces to align all the interpreter dots.</span>
<div class="viewcode-block" id="TracePrinter.go"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.TracePrinter.go">[docs]</a> <span class="k">def</span> <span class="nf">go</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a list of strings, one for each entry in the history, prefixed</span>
<span class="sd"> with enough spaces to align all the interpreter dots.</span>
<span class="sd"> This method is called internally by the ``__str__()`` method.</span>
<span class="sd"> This method is called internally by the ``__str__()`` method.</span>
<span class="sd"> :rtype: list(str)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">max_stack_length</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">lines</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="p">:</span>
<span class="n">stack</span> <span class="o">=</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">stack</span><span class="p">)</span>
<span class="n">expression</span> <span class="o">=</span> <span class="n">expression_to_string</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
<span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">stack</span><span class="p">)</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&gt;</span> <span class="n">max_stack_length</span><span class="p">:</span>
<span class="n">max_stack_length</span> <span class="o">=</span> <span class="n">n</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">n</span><span class="p">,</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><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">)))</span>
<span class="k">return</span> <span class="p">[</span> <span class="c1"># Prefix spaces to line up &#39;&#39;s.</span>
<span class="p">(</span><span class="s1">&#39; &#39;</span> <span class="o">*</span> <span class="p">(</span><span class="n">max_stack_length</span> <span class="o">-</span> <span class="n">length</span><span class="p">)</span> <span class="o">+</span> <span class="n">line</span><span class="p">)</span>
<span class="k">for</span> <span class="n">length</span><span class="p">,</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span>
<span class="p">]</span></div>
<span class="sd"> :rtype: list(str)</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">max_stack_length</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">lines</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="p">:</span>
<span class="n">stack</span> <span class="o">=</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">stack</span><span class="p">)</span>
<span class="n">expression</span> <span class="o">=</span> <span class="n">expression_to_string</span><span class="p">(</span><span class="n">expression</span><span class="p">)</span>
<span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">stack</span><span class="p">)</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&gt;</span> <span class="n">max_stack_length</span><span class="p">:</span>
<span class="n">max_stack_length</span> <span class="o">=</span> <span class="n">n</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">n</span><span class="p">,</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><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">)))</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">lines</span><span class="p">)):</span> <span class="c1"># Prefix spaces to line up &#39;&#39;s.</span>
<span class="n">length</span><span class="p">,</span> <span class="n">line</span> <span class="o">=</span> <span class="n">lines</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="n">lines</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39; &#39;</span> <span class="o">*</span> <span class="p">(</span><span class="n">max_stack_length</span> <span class="o">-</span> <span class="n">length</span><span class="p">)</span> <span class="o">+</span> <span class="n">line</span><span class="p">)</span>
<span class="k">return</span> <span class="n">lines</span></div>
<span class="k">def</span> <span class="nf">print_</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">print_exc</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Exception while printing viewer.&#39;</span><span class="p">)</span></div>
<span class="k">def</span> <span class="nf">print_</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">print_exc</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Exception while printing viewer.&#39;</span><span class="p">)</span></div>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
@ -174,17 +195,23 @@
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -195,7 +222,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>joy.utils.stack &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../../../_static/documentation_options.js"></script>
<script type="text/javascript" src="../../../_static/jquery.js"></script>
<script type="text/javascript" src="../../../_static/underscore.js"></script>
<script type="text/javascript" src="../../../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css" />
<script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
<script src="../../../_static/jquery.js"></script>
<script src="../../../_static/underscore.js"></script>
<script src="../../../_static/doctools.js"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
@ -28,6 +26,8 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for joy.utils.stack</h1><div class="highlight"><pre>
@ -76,8 +76,8 @@
<span class="sd">For example::</span>
<span class="sd"> def dup((head, tail)):</span>
<span class="sd"> return head, (head, tail)</span>
<span class="sd"> def dup((head, tail)):</span>
<span class="sd"> return head, (head, tail)</span>
<span class="sd">We replace the argument &quot;stack&quot; by the expected structure of the stack,</span>
<span class="sd">in this case &quot;(head, tail)&quot;, and Python takes care of unpacking the</span>
@ -89,9 +89,9 @@
<span class="sd">web page, doesn&#39;t handle tuples in the function parameters. And in Python 3, this</span>
<span class="sd">syntax was removed entirely. Instead you would have to write::</span>
<span class="sd"> def dup(stack):</span>
<span class="sd"> head, tail = stack</span>
<span class="sd"> return head, (head, tail)</span>
<span class="sd"> def dup(stack):</span>
<span class="sd"> head, tail = stack</span>
<span class="sd"> return head, (head, tail)</span>
<span class="sd">We have two very simple functions, one to build up a stack from a Python</span>
@ -103,138 +103,218 @@
<span class="sd">.. _cons list: https://en.wikipedia.org/wiki/Cons#Lists</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">.errors</span> <span class="kn">import</span> <span class="n">NotAListError</span>
<span class="kn">from</span> <span class="nn">builtins</span> <span class="k">import</span> <span class="nb">map</span>
<div class="viewcode-block" id="list_to_stack"><a class="viewcode-back" href="../../../stack.html#joy.utils.stack.list_to_stack">[docs]</a><span class="k">def</span> <span class="nf">list_to_stack</span><span class="p">(</span><span class="n">el</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="p">()):</span>
<span class="sd">&#39;&#39;&#39;Convert a Python list (or other sequence) to a Joy stack::</span>
<span class="sd">&#39;&#39;&#39;Convert a Python list (or other sequence) to a Joy stack::</span>
<span class="sd"> [1, 2, 3] -&gt; (1, (2, (3, ())))</span>
<span class="sd"> [1, 2, 3] -&gt; (1, (2, (3, ())))</span>
<span class="sd"> :param list el: A Python list or other sequence (iterators and generators</span>
<span class="sd"> won&#39;t work because ``reverse()`` is called on ``el``.)</span>
<span class="sd"> :param stack stack: A stack, optional, defaults to the empty stack.</span>
<span class="sd"> :rtype: stack</span>
<span class="sd"> :param list el: A Python list or other sequence (iterators and generators</span>
<span class="sd"> won&#39;t work because ``reverse()`` is called on ``el``.)</span>
<span class="sd"> :param stack stack: A stack, optional, defaults to the empty stack.</span>
<span class="sd"> :rtype: stack</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">el</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>
<span class="k">return</span> <span class="n">stack</span></div>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">el</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>
<span class="k">return</span> <span class="n">stack</span></div>
<div class="viewcode-block" id="iter_stack"><a class="viewcode-back" href="../../../stack.html#joy.utils.stack.iter_stack">[docs]</a><span class="k">def</span> <span class="nf">iter_stack</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Iterate through the items on the stack.</span>
<span class="sd">&#39;&#39;&#39;Iterate through the items on the stack.</span>
<span class="sd"> :param stack stack: A stack.</span>
<span class="sd"> :rtype: iterator</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">while</span> <span class="n">stack</span><span class="p">:</span>
<span class="n">item</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">yield</span> <span class="n">item</span></div>
<span class="sd"> :param stack stack: A stack.</span>
<span class="sd"> :rtype: iterator</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">while</span> <span class="n">stack</span><span class="p">:</span>
<span class="n">item</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">yield</span> <span class="n">item</span></div>
<div class="viewcode-block" id="stack_to_string"><a class="viewcode-back" href="../../../stack.html#joy.utils.stack.stack_to_string">[docs]</a><span class="k">def</span> <span class="nf">stack_to_string</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a &quot;pretty print&quot; string for a stack.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a &quot;pretty print&quot; string for a stack.</span>
<span class="sd"> The items are written right-to-left::</span>
<span class="sd"> The items are written right-to-left::</span>
<span class="sd"> (top, (second, ...)) -&gt; &#39;... second top&#39;</span>
<span class="sd"> (top, (second, ...)) -&gt; &#39;... second top&#39;</span>
<span class="sd"> :param stack stack: A stack.</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">f</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">stack</span><span class="p">:</span> <span class="nb">reversed</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">iter_stack</span><span class="p">(</span><span class="n">stack</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">_to_string</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span></div>
<span class="sd"> :param stack stack: A stack.</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="n">f</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">stack</span><span class="p">:</span> <span class="nb">reversed</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">iter_stack</span><span class="p">(</span><span class="n">stack</span><span class="p">)))</span>
<span class="k">return</span> <span class="n">_to_string</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span></div>
<div class="viewcode-block" id="expression_to_string"><a class="viewcode-back" href="../../../stack.html#joy.utils.stack.expression_to_string">[docs]</a><span class="k">def</span> <span class="nf">expression_to_string</span><span class="p">(</span><span class="n">expression</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a &quot;pretty print&quot; string for a expression.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return a &quot;pretty print&quot; string for a expression.</span>
<span class="sd"> The items are written left-to-right::</span>
<span class="sd"> The items are written left-to-right::</span>
<span class="sd"> (top, (second, ...)) -&gt; &#39;top second ...&#39;</span>
<span class="sd"> (top, (second, ...)) -&gt; &#39;top second ...&#39;</span>
<span class="sd"> :param stack expression: A stack.</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">return</span> <span class="n">_to_string</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">iter_stack</span><span class="p">)</span></div>
<span class="sd"> :param stack expression: A stack.</span>
<span class="sd"> :rtype: str</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">return</span> <span class="n">_to_string</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">iter_stack</span><span class="p">)</span></div>
<span class="n">_JOY_BOOL_LITS</span> <span class="o">=</span> <span class="s1">&#39;false&#39;</span><span class="p">,</span> <span class="s1">&#39;true&#39;</span>
<span class="k">def</span> <span class="nf">_joy_repr</span><span class="p">(</span><span class="n">thing</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="nb">bool</span><span class="p">):</span>
<span class="k">return</span> <span class="n">_JOY_BOOL_LITS</span><span class="p">[</span><span class="n">thing</span><span class="p">]</span>
<span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="n">thing</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_to_string</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span> <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="n">stack</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">stack</span><span class="p">:</span> <span class="k">return</span> <span class="s1">&#39;&#39;</span> <span class="c1"># shortcut</span>
<span class="k">return</span> <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">_s</span><span class="p">,</span> <span class="n">f</span><span class="p">(</span><span class="n">stack</span><span class="p">)))</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span> <span class="k">return</span> <span class="n">_joy_repr</span><span class="p">(</span><span class="n">stack</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">stack</span><span class="p">:</span> <span class="k">return</span> <span class="s1">&#39;&#39;</span> <span class="c1"># shortcut</span>
<span class="k">return</span> <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">_s</span><span class="p">,</span> <span class="n">f</span><span class="p">(</span><span class="n">stack</span><span class="p">)))</span>
<span class="n">_s</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">s</span><span class="p">:</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="n">expression_to_string</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span>
<span class="k">else</span> <span class="nb">repr</span><span class="p">(</span><span class="n">s</span><span class="p">)</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="n">expression_to_string</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span>
<span class="k">else</span> <span class="n">_joy_repr</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="p">)</span>
<div class="viewcode-block" id="concat"><a class="viewcode-back" href="../../../stack.html#joy.utils.stack.concat">[docs]</a><span class="k">def</span> <span class="nf">concat</span><span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="n">expression</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Concatinate quote onto expression.</span>
<span class="sd">&#39;&#39;&#39;Concatinate quote onto expression.</span>
<span class="sd"> In joy [1 2] [3 4] would become [1 2 3 4].</span>
<span class="sd"> In joy [1 2] [3 4] would become [1 2 3 4].</span>
<span class="sd"> :param stack quote: A stack.</span>
<span class="sd"> :param stack expression: A stack.</span>
<span class="sd"> :raises RuntimeError: if quote is larger than sys.getrecursionlimit().</span>
<span class="sd"> :rtype: stack</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="c1"># This is the fastest implementation, but will trigger</span>
<span class="c1"># RuntimeError: maximum recursion depth exceeded</span>
<span class="c1"># on quotes longer than sys.getrecursionlimit().</span>
<span class="sd"> :param stack quote: A stack.</span>
<span class="sd"> :param stack expression: A stack.</span>
<span class="sd"> :raises RuntimeError: if quote is larger than sys.getrecursionlimit().</span>
<span class="sd"> :rtype: stack</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="c1"># This is the fastest implementation, but will trigger</span>
<span class="c1"># RuntimeError: maximum recursion depth exceeded</span>
<span class="c1"># on quotes longer than sys.getrecursionlimit().</span>
<span class="k">return</span> <span class="p">(</span><span class="n">quote</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">concat</span><span class="p">(</span><span class="n">quote</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">expression</span><span class="p">))</span> <span class="k">if</span> <span class="n">quote</span> <span class="k">else</span> <span class="n">expression</span></div>
<span class="c1">## return (quote[0], concat(quote[1], expression)) if quote else expression</span>
<span class="c1"># Original implementation.</span>
<span class="c1"># Original implementation.</span>
<span class="c1">## return list_to_stack(list(iter_stack(quote)), expression)</span>
<span class="c1"># In-lining is slightly faster (and won&#39;t break the</span>
<span class="c1"># recursion limit on long quotes.)</span>
<span class="c1"># In-lining is slightly faster (and won&#39;t break the</span>
<span class="c1"># recursion limit on long quotes.)</span>
<span class="c1">## temp = []</span>
<span class="c1">## while quote:</span>
<span class="c1">## item, quote = quote</span>
<span class="c1">## temp.append(item)</span>
<span class="c1">## for item in reversed(temp):</span>
<span class="c1">## expression = item, expression</span>
<span class="c1">## return expression</span>
<span class="n">temp</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">while</span> <span class="n">quote</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">quote</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">NotAListError</span><span class="p">(</span><span class="s1">&#39;Not a list.&#39;</span><span class="p">)</span>
<span class="n">item</span><span class="p">,</span> <span class="n">quote</span> <span class="o">=</span> <span class="n">quote</span>
<span class="n">temp</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">temp</span><span class="p">):</span>
<span class="n">expression</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">expression</span>
<span class="k">return</span> <span class="n">expression</span></div>
<div class="viewcode-block" id="dnd"><a class="viewcode-back" href="../../../stack.html#joy.utils.stack.dnd">[docs]</a><span class="k">def</span> <span class="nf">dnd</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">from_index</span><span class="p">,</span> <span class="n">to_index</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Given a stack and two indices return a rearranged stack.</span>
<span class="sd"> First remove the item at from_index and then insert it at to_index,</span>
<span class="sd"> the second index is relative to the stack after removal of the item</span>
<span class="sd"> at from_index.</span>
<span class="sd"> This function reuses all of the items and as much of the stack as it</span>
<span class="sd"> can. It&#39;s meant to be used by remote clients to support drag-n-drop</span>
<span class="sd"> rearranging of the stack from e.g. the StackListbox.</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">assert</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">from_index</span>
<span class="k">assert</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">to_index</span>
<span class="k">if</span> <span class="n">from_index</span> <span class="o">==</span> <span class="n">to_index</span><span class="p">:</span>
<span class="k">return</span> <span class="n">stack</span>
<span class="n">head</span><span class="p">,</span> <span class="n">n</span> <span class="o">=</span> <span class="p">[],</span> <span class="n">from_index</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">item</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="n">n</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">head</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">head</span><span class="p">)</span> <span class="o">==</span> <span class="n">from_index</span>
<span class="c1"># now we have two cases:</span>
<span class="n">diff</span> <span class="o">=</span> <span class="n">from_index</span> <span class="o">-</span> <span class="n">to_index</span>
<span class="k">if</span> <span class="n">diff</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># from &lt; to</span>
<span class="c1"># so the destination index is still in the stack</span>
<span class="k">while</span> <span class="n">diff</span><span class="p">:</span>
<span class="n">h</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="n">head</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
<span class="n">diff</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># from &gt; to</span>
<span class="c1"># so the destination is in the head list</span>
<span class="k">while</span> <span class="n">diff</span><span class="p">:</span>
<span class="n">stack</span> <span class="o">=</span> <span class="n">head</span><span class="o">.</span><span class="n">pop</span><span class="p">(),</span> <span class="n">stack</span>
<span class="n">diff</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="n">stack</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">stack</span>
<span class="k">while</span> <span class="n">head</span><span class="p">:</span>
<span class="n">stack</span> <span class="o">=</span> <span class="n">head</span><span class="o">.</span><span class="n">pop</span><span class="p">(),</span> <span class="n">stack</span>
<span class="k">return</span> <span class="n">stack</span></div>
<div class="viewcode-block" id="pick"><a class="viewcode-back" href="../../../stack.html#joy.utils.stack.pick">[docs]</a><span class="k">def</span> <span class="nf">pick</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return the nth item on the stack.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="sd"> Return the nth item on the stack.</span>
<span class="sd"> :param stack stack: A stack.</span>
<span class="sd"> :param int n: An index into the stack.</span>
<span class="sd"> :raises ValueError: if ``n`` is less than zero.</span>
<span class="sd"> :raises IndexError: if ``n`` is equal to or greater than the length of ``stack``.</span>
<span class="sd"> :rtype: whatever</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">item</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">IndexError</span>
<span class="n">n</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">return</span> <span class="n">item</span></div>
<span class="sd"> :param stack stack: A stack.</span>
<span class="sd"> :param int n: An index into the stack.</span>
<span class="sd"> :raises ValueError: if ``n`` is less than zero.</span>
<span class="sd"> :raises IndexError: if ``n`` is equal to or greater than the length of ``stack``.</span>
<span class="sd"> :rtype: whatever</span>
<span class="sd"> &#39;&#39;&#39;</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">item</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">IndexError</span>
<span class="n">n</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">break</span>
<span class="k">return</span> <span class="n">item</span></div>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
@ -244,17 +324,23 @@
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -265,7 +351,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -0,0 +1,17 @@
***********************
Categorical Programming
***********************
DRAFT
`Categorical <https://en.wikipedia.org/wiki/Category_theory>`__
In Manfred von Thun's article `Joy compared with other functional languages <http://www.kevinalbrecht.com/code/joy-mirror/j08cnt.html>`__ he asks, "Could the language of categories be used for writing programs? Any lambda expression can be translated into a categorical expression, so the language of categories is expressively complete. But this does not make it a suitable language for writing programs. As it stands it is a very low-level language."
In `Compiling to categories <http://conal.net/papers/compiling-to-categories/>`__ Conal Elliott give a taste of what this might mean.
It is well-known that the simply typed lambda-calculus is modeled by any cartesian closed category (CCC). This correspondence suggests giving typed functional programs a variety of interpretations, each corresponding to a different category. A convenient way to realize this idea is as a collection of meaning-preserving transformations added to an existing compiler, such as GHC for Haskell. This paper describes such an implementation and demonstrates its use for a variety of interpretations including hardware circuits, automatic differentiation, incremental computation, and interval analysis. Each such interpretation is a category easily defined in Haskell (outside of the compiler). The general technique appears to provide a compelling alternative to deeply embedded domain-specific languages.
What he's doing is translating lambda forms into a kind of "point-free" style that is very close to Joy code (although more verbose) and then showing how to instantiate that code over different categories to get several different kinds of program out of the same code.

View File

@ -0,0 +1,946 @@
∂RE
===
Brzozowskis Derivatives of Regular Expressions
-----------------------------------------------
Legend:
::
∧ intersection
union
∘ concatenation (see below)
¬ complement
ϕ empty set (aka ∅)
λ singleton set containing just the empty string
I set of all letters in alphabet
Derivative of a set ``R`` of strings and a string ``a``:
::
∂a(R)
∂a(a) → λ
∂a(λ) → ϕ
∂a(ϕ) → ϕ
∂a(¬a) → ϕ
∂a(R*) → ∂a(R)∘R*
∂a(¬R) → ¬∂a(R)
∂a(R∘S) → ∂a(R)∘S δ(R)∘∂a(S)
∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
∂a(R S) → ∂a(R) ∂a(S)
∂ab(R) = ∂b(∂a(R))
Auxiliary predicate function ``δ`` (I call it ``nully``) returns either
``λ`` if ``λ ⊆ R`` or ``ϕ`` otherwise:
::
δ(a) → ϕ
δ(λ) → λ
δ(ϕ) → ϕ
δ(R*) → λ
δ(¬R) δ(R)≟ϕ → λ
δ(¬R) δ(R)≟λ → ϕ
δ(R∘S) → δ(R) ∧ δ(S)
δ(R ∧ S) → δ(R) ∧ δ(S)
δ(R S) → δ(R) δ(S)
Some rules we will use later for “compaction”:
::
R ∧ ϕ = ϕ ∧ R = ϕ
R ∧ I = I ∧ R = R
R ϕ = ϕ R = R
R I = I R = I
R∘ϕ = ϕ∘R = ϕ
R∘λ = λ∘R = R
Concatination of sets: for two sets A and B the set A∘B is defined as:
{a∘b for a in A for b in B}
E.g.:
{a, b}∘{c, d} → {ac, ad, bc, bd}
Implementation
--------------
.. code:: python
from functools import partial as curry
from itertools import product
``ϕ`` and ``λ``
~~~~~~~~~~~~~~~
The empty set and the set of just the empty string.
.. code:: ipython2
phi = frozenset() # ϕ
y = frozenset({''}) # λ
Two-letter Alphabet
~~~~~~~~~~~~~~~~~~~
Im only going to use two symbols (at first) becaase this is enough to
illustrate the algorithm and because you can represent any other
alphabet with two symbols (if you had to.)
I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
look like ``0`` and ``1`` (zero and one) respectively.
.. code:: ipython2
syms = O, l = frozenset({'0'}), frozenset({'1'})
Representing Regular Expressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To represent REs in Python Im going to use tagged tuples. A *regular
expression* is one of:
::
O
l
(KSTAR, R)
(NOT, R)
(AND, R, S)
(CONS, R, S)
(OR, R, S)
Where ``R`` and ``S`` stand for *regular expressions*.
.. code:: ipython2
AND, CONS, KSTAR, NOT, OR = 'and cons * not or'.split() # Tags are just strings.
Because they are formed of ``frozenset``, ``tuple`` and ``str`` objects
only, these datastructures are immutable.
String Representation of RE Datastructures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: ipython2
def stringy(re):
'''
Return a nice string repr for a regular expression datastructure.
'''
if re == I: return '.'
if re in syms: return next(iter(re))
if re == y: return '^'
if re == phi: return 'X'
assert isinstance(re, tuple), repr(re)
tag = re[0]
if tag == KSTAR:
body = stringy(re[1])
if not body: return body
if len(body) > 1: return '(' + body + ")*"
return body + '*'
if tag == NOT:
body = stringy(re[1])
if not body: return body
if len(body) > 1: return '(' + body + ")'"
return body + "'"
r, s = stringy(re[1]), stringy(re[2])
if tag == CONS: return r + s
if tag == OR: return '%s | %s' % (r, s)
if tag == AND: return '(%s) & (%s)' % (r, s)
raise ValueError
``I``
~~~~~
Match anything. Often spelled “.”
::
I = (0|1)*
.. code:: ipython2
I = (KSTAR, (OR, O, l))
.. code:: ipython2
print stringy(I)
.. parsed-literal::
.
``(.111.) & (.01 + 11*)'``
~~~~~~~~~~~~~~~~~~~~~~~~~~
The example expression from Brzozowski:
::
(.111.) & (.01 + 11*)'
a & (b + c)'
Note that it contains one of everything.
.. code:: ipython2
a = (CONS, I, (CONS, l, (CONS, l, (CONS, l, I))))
b = (CONS, I, (CONS, O, l))
c = (CONS, l, (KSTAR, l))
it = (AND, a, (NOT, (OR, b, c)))
.. code:: ipython2
print stringy(it)
.. parsed-literal::
(.111.) & ((.01 | 11*)')
``nully()``
~~~~~~~~~~~
Lets get that auxiliary predicate function ``δ`` out of the way.
.. code:: ipython2
def nully(R):
'''
δ - Return λ if λ ⊆ R otherwise ϕ.
'''
# δ(a) → ϕ
# δ(ϕ) → ϕ
if R in syms or R == phi:
return phi
# δ(λ) → λ
if R == y:
return y
tag = R[0]
# δ(R*) → λ
if tag == KSTAR:
return y
# δ(¬R) δ(R)≟ϕ → λ
# δ(¬R) δ(R)≟λ → ϕ
if tag == NOT:
return phi if nully(R[1]) else y
# δ(R∘S) → δ(R) ∧ δ(S)
# δ(R ∧ S) → δ(R) ∧ δ(S)
# δ(R S) → δ(R) δ(S)
r, s = nully(R[1]), nully(R[2])
return r & s if tag in {AND, CONS} else r | s
No “Compaction”
~~~~~~~~~~~~~~~
This is the straightforward version with no “compaction”. It works fine,
but does waaaay too much work because the expressions grow each
derivation.
.. code:: ipython2
def D(symbol):
def derv(R):
# ∂a(a) → λ
if R == {symbol}:
return y
# ∂a(λ) → ϕ
# ∂a(ϕ) → ϕ
# ∂a(¬a) → ϕ
if R == y or R == phi or R in syms:
return phi
tag = R[0]
# ∂a(R*) → ∂a(R)∘R*
if tag == KSTAR:
return (CONS, derv(R[1]), R)
# ∂a(¬R) → ¬∂a(R)
if tag == NOT:
return (NOT, derv(R[1]))
r, s = R[1:]
# ∂a(R∘S) → ∂a(R)∘S δ(R)∘∂a(S)
if tag == CONS:
A = (CONS, derv(r), s) # A = ∂a(R)∘S
# A δ(R) ∘ ∂a(S)
# A λ ∘ ∂a(S) → A ∂a(S)
# A ϕ ∘ ∂a(S) → A ϕ → A
return (OR, A, derv(s)) if nully(r) else A
# ∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
# ∂a(R S) → ∂a(R) ∂a(S)
return (tag, derv(r), derv(s))
return derv
Compaction Rules
~~~~~~~~~~~~~~~~
.. code:: ipython2
def _compaction_rule(relation, one, zero, a, b):
return (
b if a == one else # R*1 = 1*R = R
a if b == one else
zero if a == zero or b == zero else # R*0 = 0*R = 0
(relation, a, b)
)
An elegant symmetry.
.. code:: ipython2
# R ∧ I = I ∧ R = R
# R ∧ ϕ = ϕ ∧ R = ϕ
_and = curry(_compaction_rule, AND, I, phi)
# R ϕ = ϕ R = R
# R I = I R = I
_or = curry(_compaction_rule, OR, phi, I)
# R∘λ = λ∘R = R
# R∘ϕ = ϕ∘R = ϕ
_cons = curry(_compaction_rule, CONS, y, phi)
Memoizing
~~~~~~~~~
We can save re-processing by remembering results we have already
computed. RE datastructures are immutable and the ``derv()`` functions
are *pure* so this is fine.
.. code:: ipython2
class Memo(object):
def __init__(self, f):
self.f = f
self.calls = self.hits = 0
self.mem = {}
def __call__(self, key):
self.calls += 1
try:
result = self.mem[key]
self.hits += 1
except KeyError:
result = self.mem[key] = self.f(key)
return result
With “Compaction”
~~~~~~~~~~~~~~~~~
This version uses the rules above to perform compaction. It keeps the
expressions from growing too large.
.. code:: ipython2
def D_compaction(symbol):
@Memo
def derv(R):
# ∂a(a) → λ
if R == {symbol}:
return y
# ∂a(λ) → ϕ
# ∂a(ϕ) → ϕ
# ∂a(¬a) → ϕ
if R == y or R == phi or R in syms:
return phi
tag = R[0]
# ∂a(R*) → ∂a(R)∘R*
if tag == KSTAR:
return _cons(derv(R[1]), R)
# ∂a(¬R) → ¬∂a(R)
if tag == NOT:
return (NOT, derv(R[1]))
r, s = R[1:]
# ∂a(R∘S) → ∂a(R)∘S δ(R)∘∂a(S)
if tag == CONS:
A = _cons(derv(r), s) # A = ∂a(r)∘s
# A δ(R) ∘ ∂a(S)
# A λ ∘ ∂a(S) → A ∂a(S)
# A ϕ ∘ ∂a(S) → A ϕ → A
return _or(A, derv(s)) if nully(r) else A
# ∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
# ∂a(R S) → ∂a(R) ∂a(S)
dr, ds = derv(r), derv(s)
return _and(dr, ds) if tag == AND else _or(dr, ds)
return derv
Lets try it out…
-----------------
(FIXME: redo.)
.. code:: ipython2
o, z = D_compaction('0'), D_compaction('1')
REs = set()
N = 5
names = list(product(*(N * [(0, 1)])))
dervs = list(product(*(N * [(o, z)])))
for name, ds in zip(names, dervs):
R = it
ds = list(ds)
while ds:
R = ds.pop()(R)
if R == phi or R == I:
break
REs.add(R)
print stringy(it) ; print
print o.hits, '/', o.calls
print z.hits, '/', z.calls
print
for s in sorted(map(stringy, REs), key=lambda n: (len(n), n)):
print s
.. parsed-literal::
(.111.) & ((.01 | 11*)')
92 / 122
92 / 122
(.01)'
(.01 | 1)'
(.01 | ^)'
(.01 | 1*)'
(.111.) & ((.01 | 1)')
(.111. | 11.) & ((.01 | ^)')
(.111. | 11. | 1.) & ((.01)')
(.111. | 11.) & ((.01 | 1*)')
(.111. | 11. | 1.) & ((.01 | 1*)')
Should match:
::
(.111.) & ((.01 | 11*)')
92 / 122
92 / 122
(.01 )'
(.01 | 1 )'
(.01 | ^ )'
(.01 | 1*)'
(.111.) & ((.01 | 1 )')
(.111. | 11.) & ((.01 | ^ )')
(.111. | 11.) & ((.01 | 1*)')
(.111. | 11. | 1.) & ((.01 )')
(.111. | 11. | 1.) & ((.01 | 1*)')
Larger Alphabets
----------------
We could parse larger alphabets by defining patterns for e.g. each byte
of the ASCII code. Or we can generalize this code. If you study the code
above youll see that we never use the “set-ness” of the symbols ``O``
and ``l``. The only time Python set operators (``&`` and ``|``) appear
is in the ``nully()`` function, and there they operate on (recursively
computed) outputs of that function, never ``O`` and ``l``.
What if we try:
::
(OR, O, l)
∂1((OR, O, l))
∂a(R S) → ∂a(R) ∂a(S)
∂1(O) ∂1(l)
∂a(¬a) → ϕ
ϕ ∂1(l)
∂a(a) → λ
ϕ λ
ϕ R = R
λ
And compare it to:
::
{'0', '1')
∂1({'0', '1'))
∂a(R S) → ∂a(R) ∂a(S)
∂1({'0')) ∂1({'1'))
∂a(¬a) → ϕ
ϕ ∂1({'1'))
∂a(a) → λ
ϕ λ
ϕ R = R
λ
This suggests that we should be able to alter the functions above to
detect sets and deal with them appropriately. Exercise for the Reader
for now.
State Machine
-------------
We can drive the regular expressions to flesh out the underlying state
machine transition table.
::
.111. & (.01 + 11*)'
Says, “Three or more 1s and not ending in 01 nor composed of all 1s.”
.. figure:: omg.svg
:alt: State Machine Graph
State Machine Graph
Start at ``a`` and follow the transition arrows according to their
labels. Accepting states have a double outline. (Graphic generated with
`Dot from Graphviz <http://www.graphviz.org/>`__.) Youll see that only
paths that lead to one of the accepting states will match the regular
expression. All other paths will terminate at one of the non-accepting
states.
Theres a happy path to ``g`` along 111:
::
a→c→e→g
After you reach ``g`` youre stuck there eating 1s until you see a 0,
which takes you to the ``i→j→i|i→j→h→i`` “trap”. You cant reach any
other states from those two loops.
If you see a 0 before you see 111 you will reach ``b``, which forms
another “trap” with ``d`` and ``f``. The only way out is another happy
path along 111 to ``h``:
::
b→d→f→h
Once you have reached ``h`` you can see as many 1s or as many 0 in a
row and still be either still at ``h`` (for 1s) or move to ``i`` (for
0s). If you find yourself at ``i`` you can see as many 0s, or
repetitions of 10, as there are, but if you see just a 1 you move to
``j``.
RE to FSM
~~~~~~~~~
So how do we get the state machine from the regular expression?
It turns out that each RE is effectively a state, and each arrow points
to the derivative RE in respect to the arrows symbol.
If we label the initial RE ``a``, we can say:
::
a --0--> ∂0(a)
a --1--> ∂1(a)
And so on, each new unique RE is a new state in the FSM table.
Here are the derived REs at each state:
::
a = (.111.) & ((.01 | 11*)')
b = (.111.) & ((.01 | 1)')
c = (.111. | 11.) & ((.01 | 1*)')
d = (.111. | 11.) & ((.01 | ^)')
e = (.111. | 11. | 1.) & ((.01 | 1*)')
f = (.111. | 11. | 1.) & ((.01)')
g = (.01 | 1*)'
h = (.01)'
i = (.01 | 1)'
j = (.01 | ^)'
You can see the one-way nature of the ``g`` state and the ``hij`` “trap”
in the way that the ``.111.`` on the left-hand side of the ``&``
disappears once it has been matched.
.. code:: ipython2
from collections import defaultdict
from pprint import pprint
from string import ascii_lowercase
.. code:: ipython2
d0, d1 = D_compaction('0'), D_compaction('1')
``explore()``
~~~~~~~~~~~~~
.. code:: ipython2
def explore(re):
# Don't have more than 26 states...
names = defaultdict(iter(ascii_lowercase).next)
table, accepting = dict(), set()
to_check = {re}
while to_check:
re = to_check.pop()
state_name = names[re]
if (state_name, 0) in table:
continue
if nully(re):
accepting.add(state_name)
o, i = d0(re), d1(re)
table[state_name, 0] = names[o] ; to_check.add(o)
table[state_name, 1] = names[i] ; to_check.add(i)
return table, accepting
.. code:: ipython2
table, accepting = explore(it)
table
.. parsed-literal::
{('a', 0): 'b',
('a', 1): 'c',
('b', 0): 'b',
('b', 1): 'd',
('c', 0): 'b',
('c', 1): 'e',
('d', 0): 'b',
('d', 1): 'f',
('e', 0): 'b',
('e', 1): 'g',
('f', 0): 'b',
('f', 1): 'h',
('g', 0): 'i',
('g', 1): 'g',
('h', 0): 'i',
('h', 1): 'h',
('i', 0): 'i',
('i', 1): 'j',
('j', 0): 'i',
('j', 1): 'h'}
.. code:: ipython2
accepting
.. parsed-literal::
{'h', 'i'}
Generate Diagram
~~~~~~~~~~~~~~~~
Once we have the FSM table and the set of accepting states we can
generate the diagram above.
.. code:: ipython2
_template = '''\
digraph finite_state_machine {
rankdir=LR;
size="8,5"
node [shape = doublecircle]; %s;
node [shape = circle];
%s
}
'''
def link(fr, nm, label):
return ' %s -> %s [ label = "%s" ];' % (fr, nm, label)
def make_graph(table, accepting):
return _template % (
' '.join(accepting),
'\n'.join(
link(from_, to, char)
for (from_, char), (to) in sorted(table.iteritems())
)
)
.. code:: ipython2
print make_graph(table, accepting)
.. parsed-literal::
digraph finite_state_machine {
rankdir=LR;
size="8,5"
node [shape = doublecircle]; i h;
node [shape = circle];
a -> b [ label = "0" ];
a -> c [ label = "1" ];
b -> b [ label = "0" ];
b -> d [ label = "1" ];
c -> b [ label = "0" ];
c -> e [ label = "1" ];
d -> b [ label = "0" ];
d -> f [ label = "1" ];
e -> b [ label = "0" ];
e -> g [ label = "1" ];
f -> b [ label = "0" ];
f -> h [ label = "1" ];
g -> i [ label = "0" ];
g -> g [ label = "1" ];
h -> i [ label = "0" ];
h -> h [ label = "1" ];
i -> i [ label = "0" ];
i -> j [ label = "1" ];
j -> i [ label = "0" ];
j -> h [ label = "1" ];
}
Drive a FSM
~~~~~~~~~~~
There are *lots* of FSM libraries already. Once you have the state
transition table they should all be straightforward to use. State
Machine code is very simple. Just for fun, here is an implementation in
Python that imitates what “compiled” FSM code might look like in an
“unrolled” form. Most FSM code uses a little driver loop and a table
datastructure, the code below instead acts like JMP instructions
(“jump”, or GOTO in higher-level-but-still-low-level languages) to
hard-code the information in the table into a little patch of branches.
Trampoline Function
^^^^^^^^^^^^^^^^^^^
Python has no GOTO statement but we can fake it with a “trampoline”
function.
.. code:: ipython2
def trampoline(input_, jump_from, accepting):
I = iter(input_)
while True:
try:
bounce_to = jump_from(I)
except StopIteration:
return jump_from in accepting
jump_from = bounce_to
Stream Functions
^^^^^^^^^^^^^^^^
Little helpers to process the iterator of our data (a “stream” of “1”
and “0” characters, not bits.)
.. code:: ipython2
getch = lambda I: int(next(I))
def _1(I):
'''Loop on ones.'''
while getch(I): pass
def _0(I):
'''Loop on zeros.'''
while not getch(I): pass
A Finite State Machine
^^^^^^^^^^^^^^^^^^^^^^
With those preliminaries out of the way, from the state table of
``.111. & (.01 + 11*)'`` we can immediately write down state machine
code. (You have to imagine that these are GOTO statements in C or
branches in assembly and that the state names are branch destination
labels.)
.. code:: ipython2
a = lambda I: c if getch(I) else b
b = lambda I: _0(I) or d
c = lambda I: e if getch(I) else b
d = lambda I: f if getch(I) else b
e = lambda I: g if getch(I) else b
f = lambda I: h if getch(I) else b
g = lambda I: _1(I) or i
h = lambda I: _1(I) or i
i = lambda I: _0(I) or j
j = lambda I: h if getch(I) else i
Note that the implementations of ``h`` and ``g`` are identical ergo
``h = g`` and we could eliminate one in the code but ``h`` is an
accepting state and ``g`` isnt.
.. code:: ipython2
def acceptable(input_):
return trampoline(input_, a, {h, i})
.. code:: ipython2
for n in range(2**5):
s = bin(n)[2:]
print '%05s' % s, acceptable(s)
.. parsed-literal::
0 False
1 False
10 False
11 False
100 False
101 False
110 False
111 False
1000 False
1001 False
1010 False
1011 False
1100 False
1101 False
1110 True
1111 False
10000 False
10001 False
10010 False
10011 False
10100 False
10101 False
10110 False
10111 True
11000 False
11001 False
11010 False
11011 False
11100 True
11101 False
11110 True
11111 False
Reversing the Derivatives to Generate Matching Strings
------------------------------------------------------
(UNFINISHED) Brzozowski also shewed how to go from the state machine to
strings and expressions…
Each of these states is just a name for a Brzozowskian RE, and so, other
than the initial state ``a``, they can can be described in terms of the
derivative-with-respect-to-N of some other state/RE:
::
c = d1(a)
b = d0(a)
b = d0(c)
...
i = d0(j)
j = d1(i)
Consider:
::
c = d1(a)
b = d0(c)
Substituting:
::
b = d0(d1(a))
Unwrapping:
::
b = d10(a)
::
j = d1(d0(j))
Unwrapping:
::
j = d1(d0(j)) = d01(j)
We have a loop or “fixed point”.
::
j = d01(j) = d0101(j) = d010101(j) = ...
hmm…
::
j = (01)*

View File

@ -0,0 +1,815 @@
***************************
Developing a Program in Joy
***************************
As an example of developing a program in Joy let's take the first problem from the Project Euler website.
`Project Euler, first problem: "Multiples of 3 and 5" <https://projecteuler.net/problem=1>`__
=============================================================================================
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
.. code:: ipython2
from notebook_preamble import J, V, define
Sum a range filtered by a predicate
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Let's create a predicate that returns ``True`` if a number is a multiple
of 3 or 5 and ``False`` otherwise.
.. code:: ipython2
define('P == [3 % not] dupdip 5 % not or')
.. code:: ipython2
V('80 P')
.. parsed-literal::
. 80 P
80 . P
80 . [3 % not] dupdip 5 % not or
80 [3 % not] . dupdip 5 % not or
80 . 3 % not 80 5 % not or
80 3 . % not 80 5 % not or
2 . not 80 5 % not or
False . 80 5 % not or
False 80 . 5 % not or
False 80 5 . % not or
False 0 . not or
False True . or
True .
Given the predicate function ``P`` a suitable program is:
::
PE1 == 1000 range [P] filter sum
This function generates a list of the integers from 0 to 999, filters
that list by ``P``, and then sums the result.
Logically this is fine, but pragmatically we are doing more work than we
should be; we generate one thousand integers but actually use less than
half of them. A better solution would be to generate just the multiples
we want to sum, and to add them as we go rather than storing them and
and summing them at the end.
Generate just the multiples
^^^^^^^^^^^^^^^^^^^^^^^^^^^
At first I had the idea to use two counters and increase them by three
and five, respectively. This way we only generate the terms that we
actually want to sum. We have to proceed by incrementing the counter
that is lower, or if they are equal, the three counter, and we have to
take care not to double add numbers like 15 that are multiples of both
three and five.
This seemed a little clunky, so I tried a different approach.
Consider the first few terms in the series:
::
3 5 6 9 10 12 15 18 20 21 ...
Subtract each number from the one after it (subtracting 0 from 3):
::
3 5 6 9 10 12 15 18 20 21 24 25 27 30 ...
0 3 5 6 9 10 12 15 18 20 21 24 25 27 ...
-------------------------------------------
3 2 1 3 1 2 3 3 2 1 3 1 2 3 ...
You get this lovely repeating palindromic sequence:
::
3 2 1 3 1 2 3
To make a counter that increments by factors of 3 and 5 you just add
these differences to the counter one-by-one in a loop.
To make use of this sequence to increment a counter and sum terms as we
go we need a function that will accept the sum, the counter, and the
next term to add, and that adds the term to the counter and a copy of
the counter to the running sum. This function will do that:
::
PE1.1 == + [+] dupdip
.. code:: ipython2
define('PE1.1 == + [+] dupdip')
.. code:: ipython2
V('0 0 3 PE1.1')
.. parsed-literal::
. 0 0 3 PE1.1
0 . 0 3 PE1.1
0 0 . 3 PE1.1
0 0 3 . PE1.1
0 0 3 . + [+] dupdip
0 3 . [+] dupdip
0 3 [+] . dupdip
0 3 . + 3
3 . 3
3 3 .
.. code:: ipython2
V('0 0 [3 2 1 3 1 2 3] [PE1.1] step')
.. parsed-literal::
. 0 0 [3 2 1 3 1 2 3] [PE1.1] step
0 . 0 [3 2 1 3 1 2 3] [PE1.1] step
0 0 . [3 2 1 3 1 2 3] [PE1.1] step
0 0 [3 2 1 3 1 2 3] . [PE1.1] step
0 0 [3 2 1 3 1 2 3] [PE1.1] . step
0 0 3 [PE1.1] . i [2 1 3 1 2 3] [PE1.1] step
0 0 3 . PE1.1 [2 1 3 1 2 3] [PE1.1] step
0 0 3 . + [+] dupdip [2 1 3 1 2 3] [PE1.1] step
0 3 . [+] dupdip [2 1 3 1 2 3] [PE1.1] step
0 3 [+] . dupdip [2 1 3 1 2 3] [PE1.1] step
0 3 . + 3 [2 1 3 1 2 3] [PE1.1] step
3 . 3 [2 1 3 1 2 3] [PE1.1] step
3 3 . [2 1 3 1 2 3] [PE1.1] step
3 3 [2 1 3 1 2 3] . [PE1.1] step
3 3 [2 1 3 1 2 3] [PE1.1] . step
3 3 2 [PE1.1] . i [1 3 1 2 3] [PE1.1] step
3 3 2 . PE1.1 [1 3 1 2 3] [PE1.1] step
3 3 2 . + [+] dupdip [1 3 1 2 3] [PE1.1] step
3 5 . [+] dupdip [1 3 1 2 3] [PE1.1] step
3 5 [+] . dupdip [1 3 1 2 3] [PE1.1] step
3 5 . + 5 [1 3 1 2 3] [PE1.1] step
8 . 5 [1 3 1 2 3] [PE1.1] step
8 5 . [1 3 1 2 3] [PE1.1] step
8 5 [1 3 1 2 3] . [PE1.1] step
8 5 [1 3 1 2 3] [PE1.1] . step
8 5 1 [PE1.1] . i [3 1 2 3] [PE1.1] step
8 5 1 . PE1.1 [3 1 2 3] [PE1.1] step
8 5 1 . + [+] dupdip [3 1 2 3] [PE1.1] step
8 6 . [+] dupdip [3 1 2 3] [PE1.1] step
8 6 [+] . dupdip [3 1 2 3] [PE1.1] step
8 6 . + 6 [3 1 2 3] [PE1.1] step
14 . 6 [3 1 2 3] [PE1.1] step
14 6 . [3 1 2 3] [PE1.1] step
14 6 [3 1 2 3] . [PE1.1] step
14 6 [3 1 2 3] [PE1.1] . step
14 6 3 [PE1.1] . i [1 2 3] [PE1.1] step
14 6 3 . PE1.1 [1 2 3] [PE1.1] step
14 6 3 . + [+] dupdip [1 2 3] [PE1.1] step
14 9 . [+] dupdip [1 2 3] [PE1.1] step
14 9 [+] . dupdip [1 2 3] [PE1.1] step
14 9 . + 9 [1 2 3] [PE1.1] step
23 . 9 [1 2 3] [PE1.1] step
23 9 . [1 2 3] [PE1.1] step
23 9 [1 2 3] . [PE1.1] step
23 9 [1 2 3] [PE1.1] . step
23 9 1 [PE1.1] . i [2 3] [PE1.1] step
23 9 1 . PE1.1 [2 3] [PE1.1] step
23 9 1 . + [+] dupdip [2 3] [PE1.1] step
23 10 . [+] dupdip [2 3] [PE1.1] step
23 10 [+] . dupdip [2 3] [PE1.1] step
23 10 . + 10 [2 3] [PE1.1] step
33 . 10 [2 3] [PE1.1] step
33 10 . [2 3] [PE1.1] step
33 10 [2 3] . [PE1.1] step
33 10 [2 3] [PE1.1] . step
33 10 2 [PE1.1] . i [3] [PE1.1] step
33 10 2 . PE1.1 [3] [PE1.1] step
33 10 2 . + [+] dupdip [3] [PE1.1] step
33 12 . [+] dupdip [3] [PE1.1] step
33 12 [+] . dupdip [3] [PE1.1] step
33 12 . + 12 [3] [PE1.1] step
45 . 12 [3] [PE1.1] step
45 12 . [3] [PE1.1] step
45 12 [3] . [PE1.1] step
45 12 [3] [PE1.1] . step
45 12 3 [PE1.1] . i
45 12 3 . PE1.1
45 12 3 . + [+] dupdip
45 15 . [+] dupdip
45 15 [+] . dupdip
45 15 . + 15
60 . 15
60 15 .
So one ``step`` through all seven terms brings the counter to 15 and the
total to 60.
How many multiples to sum?
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code:: ipython2
1000 / 15
.. parsed-literal::
66
.. code:: ipython2
66 * 15
.. parsed-literal::
990
.. code:: ipython2
1000 - 990
.. parsed-literal::
10
We only want the terms *less than* 1000.
.. code:: ipython2
999 - 990
.. parsed-literal::
9
That means we want to run the full list of numbers sixty-six times to
get to 990 and then the first four numbers 3 2 1 3 to get to 999.
.. code:: ipython2
define('PE1 == 0 0 66 [[3 2 1 3 1 2 3] [PE1.1] step] times [3 2 1 3] [PE1.1] step pop')
.. code:: ipython2
J('PE1')
.. parsed-literal::
233168
Packing the terms into an integer
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This form uses no extra storage and produces no unused summands. It's
good but there's one more trick we can apply. The list of seven terms
takes up at least seven bytes. But notice that all of the terms are less
than four, and so each can fit in just two bits. We could store all
seven terms in just fourteen bits and use masking and shifts to pick out
each term as we go. This will use less space and save time loading whole
integer terms from the list.
::
3 2 1 3 1 2 3
0b 11 10 01 11 01 10 11 == 14811
.. code:: ipython2
0b11100111011011
.. parsed-literal::
14811
.. code:: ipython2
define('PE1.2 == [3 & PE1.1] dupdip 2 >>')
.. code:: ipython2
V('0 0 14811 PE1.2')
.. parsed-literal::
. 0 0 14811 PE1.2
0 . 0 14811 PE1.2
0 0 . 14811 PE1.2
0 0 14811 . PE1.2
0 0 14811 . [3 & PE1.1] dupdip 2 >>
0 0 14811 [3 & PE1.1] . dupdip 2 >>
0 0 14811 . 3 & PE1.1 14811 2 >>
0 0 14811 3 . & PE1.1 14811 2 >>
0 0 3 . PE1.1 14811 2 >>
0 0 3 . + [+] dupdip 14811 2 >>
0 3 . [+] dupdip 14811 2 >>
0 3 [+] . dupdip 14811 2 >>
0 3 . + 3 14811 2 >>
3 . 3 14811 2 >>
3 3 . 14811 2 >>
3 3 14811 . 2 >>
3 3 14811 2 . >>
3 3 3702 .
.. code:: ipython2
V('3 3 3702 PE1.2')
.. parsed-literal::
. 3 3 3702 PE1.2
3 . 3 3702 PE1.2
3 3 . 3702 PE1.2
3 3 3702 . PE1.2
3 3 3702 . [3 & PE1.1] dupdip 2 >>
3 3 3702 [3 & PE1.1] . dupdip 2 >>
3 3 3702 . 3 & PE1.1 3702 2 >>
3 3 3702 3 . & PE1.1 3702 2 >>
3 3 2 . PE1.1 3702 2 >>
3 3 2 . + [+] dupdip 3702 2 >>
3 5 . [+] dupdip 3702 2 >>
3 5 [+] . dupdip 3702 2 >>
3 5 . + 5 3702 2 >>
8 . 5 3702 2 >>
8 5 . 3702 2 >>
8 5 3702 . 2 >>
8 5 3702 2 . >>
8 5 925 .
.. code:: ipython2
V('0 0 14811 7 [PE1.2] times pop')
.. parsed-literal::
. 0 0 14811 7 [PE1.2] times pop
0 . 0 14811 7 [PE1.2] times pop
0 0 . 14811 7 [PE1.2] times pop
0 0 14811 . 7 [PE1.2] times pop
0 0 14811 7 . [PE1.2] times pop
0 0 14811 7 [PE1.2] . times pop
0 0 14811 [PE1.2] . i 6 [PE1.2] times pop
0 0 14811 . PE1.2 6 [PE1.2] times pop
0 0 14811 . [3 & PE1.1] dupdip 2 >> 6 [PE1.2] times pop
0 0 14811 [3 & PE1.1] . dupdip 2 >> 6 [PE1.2] times pop
0 0 14811 . 3 & PE1.1 14811 2 >> 6 [PE1.2] times pop
0 0 14811 3 . & PE1.1 14811 2 >> 6 [PE1.2] times pop
0 0 3 . PE1.1 14811 2 >> 6 [PE1.2] times pop
0 0 3 . + [+] dupdip 14811 2 >> 6 [PE1.2] times pop
0 3 . [+] dupdip 14811 2 >> 6 [PE1.2] times pop
0 3 [+] . dupdip 14811 2 >> 6 [PE1.2] times pop
0 3 . + 3 14811 2 >> 6 [PE1.2] times pop
3 . 3 14811 2 >> 6 [PE1.2] times pop
3 3 . 14811 2 >> 6 [PE1.2] times pop
3 3 14811 . 2 >> 6 [PE1.2] times pop
3 3 14811 2 . >> 6 [PE1.2] times pop
3 3 3702 . 6 [PE1.2] times pop
3 3 3702 6 . [PE1.2] times pop
3 3 3702 6 [PE1.2] . times pop
3 3 3702 [PE1.2] . i 5 [PE1.2] times pop
3 3 3702 . PE1.2 5 [PE1.2] times pop
3 3 3702 . [3 & PE1.1] dupdip 2 >> 5 [PE1.2] times pop
3 3 3702 [3 & PE1.1] . dupdip 2 >> 5 [PE1.2] times pop
3 3 3702 . 3 & PE1.1 3702 2 >> 5 [PE1.2] times pop
3 3 3702 3 . & PE1.1 3702 2 >> 5 [PE1.2] times pop
3 3 2 . PE1.1 3702 2 >> 5 [PE1.2] times pop
3 3 2 . + [+] dupdip 3702 2 >> 5 [PE1.2] times pop
3 5 . [+] dupdip 3702 2 >> 5 [PE1.2] times pop
3 5 [+] . dupdip 3702 2 >> 5 [PE1.2] times pop
3 5 . + 5 3702 2 >> 5 [PE1.2] times pop
8 . 5 3702 2 >> 5 [PE1.2] times pop
8 5 . 3702 2 >> 5 [PE1.2] times pop
8 5 3702 . 2 >> 5 [PE1.2] times pop
8 5 3702 2 . >> 5 [PE1.2] times pop
8 5 925 . 5 [PE1.2] times pop
8 5 925 5 . [PE1.2] times pop
8 5 925 5 [PE1.2] . times pop
8 5 925 [PE1.2] . i 4 [PE1.2] times pop
8 5 925 . PE1.2 4 [PE1.2] times pop
8 5 925 . [3 & PE1.1] dupdip 2 >> 4 [PE1.2] times pop
8 5 925 [3 & PE1.1] . dupdip 2 >> 4 [PE1.2] times pop
8 5 925 . 3 & PE1.1 925 2 >> 4 [PE1.2] times pop
8 5 925 3 . & PE1.1 925 2 >> 4 [PE1.2] times pop
8 5 1 . PE1.1 925 2 >> 4 [PE1.2] times pop
8 5 1 . + [+] dupdip 925 2 >> 4 [PE1.2] times pop
8 6 . [+] dupdip 925 2 >> 4 [PE1.2] times pop
8 6 [+] . dupdip 925 2 >> 4 [PE1.2] times pop
8 6 . + 6 925 2 >> 4 [PE1.2] times pop
14 . 6 925 2 >> 4 [PE1.2] times pop
14 6 . 925 2 >> 4 [PE1.2] times pop
14 6 925 . 2 >> 4 [PE1.2] times pop
14 6 925 2 . >> 4 [PE1.2] times pop
14 6 231 . 4 [PE1.2] times pop
14 6 231 4 . [PE1.2] times pop
14 6 231 4 [PE1.2] . times pop
14 6 231 [PE1.2] . i 3 [PE1.2] times pop
14 6 231 . PE1.2 3 [PE1.2] times pop
14 6 231 . [3 & PE1.1] dupdip 2 >> 3 [PE1.2] times pop
14 6 231 [3 & PE1.1] . dupdip 2 >> 3 [PE1.2] times pop
14 6 231 . 3 & PE1.1 231 2 >> 3 [PE1.2] times pop
14 6 231 3 . & PE1.1 231 2 >> 3 [PE1.2] times pop
14 6 3 . PE1.1 231 2 >> 3 [PE1.2] times pop
14 6 3 . + [+] dupdip 231 2 >> 3 [PE1.2] times pop
14 9 . [+] dupdip 231 2 >> 3 [PE1.2] times pop
14 9 [+] . dupdip 231 2 >> 3 [PE1.2] times pop
14 9 . + 9 231 2 >> 3 [PE1.2] times pop
23 . 9 231 2 >> 3 [PE1.2] times pop
23 9 . 231 2 >> 3 [PE1.2] times pop
23 9 231 . 2 >> 3 [PE1.2] times pop
23 9 231 2 . >> 3 [PE1.2] times pop
23 9 57 . 3 [PE1.2] times pop
23 9 57 3 . [PE1.2] times pop
23 9 57 3 [PE1.2] . times pop
23 9 57 [PE1.2] . i 2 [PE1.2] times pop
23 9 57 . PE1.2 2 [PE1.2] times pop
23 9 57 . [3 & PE1.1] dupdip 2 >> 2 [PE1.2] times pop
23 9 57 [3 & PE1.1] . dupdip 2 >> 2 [PE1.2] times pop
23 9 57 . 3 & PE1.1 57 2 >> 2 [PE1.2] times pop
23 9 57 3 . & PE1.1 57 2 >> 2 [PE1.2] times pop
23 9 1 . PE1.1 57 2 >> 2 [PE1.2] times pop
23 9 1 . + [+] dupdip 57 2 >> 2 [PE1.2] times pop
23 10 . [+] dupdip 57 2 >> 2 [PE1.2] times pop
23 10 [+] . dupdip 57 2 >> 2 [PE1.2] times pop
23 10 . + 10 57 2 >> 2 [PE1.2] times pop
33 . 10 57 2 >> 2 [PE1.2] times pop
33 10 . 57 2 >> 2 [PE1.2] times pop
33 10 57 . 2 >> 2 [PE1.2] times pop
33 10 57 2 . >> 2 [PE1.2] times pop
33 10 14 . 2 [PE1.2] times pop
33 10 14 2 . [PE1.2] times pop
33 10 14 2 [PE1.2] . times pop
33 10 14 [PE1.2] . i 1 [PE1.2] times pop
33 10 14 . PE1.2 1 [PE1.2] times pop
33 10 14 . [3 & PE1.1] dupdip 2 >> 1 [PE1.2] times pop
33 10 14 [3 & PE1.1] . dupdip 2 >> 1 [PE1.2] times pop
33 10 14 . 3 & PE1.1 14 2 >> 1 [PE1.2] times pop
33 10 14 3 . & PE1.1 14 2 >> 1 [PE1.2] times pop
33 10 2 . PE1.1 14 2 >> 1 [PE1.2] times pop
33 10 2 . + [+] dupdip 14 2 >> 1 [PE1.2] times pop
33 12 . [+] dupdip 14 2 >> 1 [PE1.2] times pop
33 12 [+] . dupdip 14 2 >> 1 [PE1.2] times pop
33 12 . + 12 14 2 >> 1 [PE1.2] times pop
45 . 12 14 2 >> 1 [PE1.2] times pop
45 12 . 14 2 >> 1 [PE1.2] times pop
45 12 14 . 2 >> 1 [PE1.2] times pop
45 12 14 2 . >> 1 [PE1.2] times pop
45 12 3 . 1 [PE1.2] times pop
45 12 3 1 . [PE1.2] times pop
45 12 3 1 [PE1.2] . times pop
45 12 3 [PE1.2] . i pop
45 12 3 . PE1.2 pop
45 12 3 . [3 & PE1.1] dupdip 2 >> pop
45 12 3 [3 & PE1.1] . dupdip 2 >> pop
45 12 3 . 3 & PE1.1 3 2 >> pop
45 12 3 3 . & PE1.1 3 2 >> pop
45 12 3 . PE1.1 3 2 >> pop
45 12 3 . + [+] dupdip 3 2 >> pop
45 15 . [+] dupdip 3 2 >> pop
45 15 [+] . dupdip 3 2 >> pop
45 15 . + 15 3 2 >> pop
60 . 15 3 2 >> pop
60 15 . 3 2 >> pop
60 15 3 . 2 >> pop
60 15 3 2 . >> pop
60 15 0 . pop
60 15 .
And so we have at last:
.. code:: ipython2
define('PE1 == 0 0 66 [14811 7 [PE1.2] times pop] times 14811 4 [PE1.2] times popop')
.. code:: ipython2
J('PE1')
.. parsed-literal::
233168
Let's refactor
^^^^^^^^^^^^^^^
::
14811 7 [PE1.2] times pop
14811 4 [PE1.2] times pop
14811 n [PE1.2] times pop
n 14811 swap [PE1.2] times pop
.. code:: ipython2
define('PE1.3 == 14811 swap [PE1.2] times pop')
Now we can simplify the definition above:
.. code:: ipython2
define('PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop')
.. code:: ipython2
J('PE1')
.. parsed-literal::
233168
Here's our joy program all in one place. It doesn't make so much sense,
but if you have read through the above description of how it was derived
I hope it's clear.
::
PE1.1 == + [+] dupdip
PE1.2 == [3 & PE1.1] dupdip 2 >>
PE1.3 == 14811 swap [PE1.2] times pop
PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop
Generator Version
=================
It's a little clunky iterating sixty-six times though the seven numbers
then four more. In the *Generator Programs* notebook we derive a
generator that can be repeatedly driven by the ``x`` combinator to
produce a stream of the seven numbers repeating over and over again.
.. code:: ipython2
define('PE1.terms == [0 swap [dup [pop 14811] [] branch [3 &] dupdip 2 >>] dip rest cons]')
.. code:: ipython2
J('PE1.terms 21 [x] times')
.. parsed-literal::
3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 [0 swap [dup [pop 14811] [] branch [3 &] dupdip 2 >>] dip rest cons]
We know from above that we need sixty-six times seven then four more
terms to reach up to but not over one thousand.
.. code:: ipython2
J('7 66 * 4 +')
.. parsed-literal::
466
Here they are...
~~~~~~~~~~~~~~~~
.. code:: ipython2
J('PE1.terms 466 [x] times pop')
.. parsed-literal::
3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3
...and they do sum to 999.
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: ipython2
J('[PE1.terms 466 [x] times pop] run sum')
.. parsed-literal::
999
Now we can use ``PE1.1`` to accumulate the terms as we go, and then
``pop`` the generator and the counter from the stack when we're done,
leaving just the sum.
.. code:: ipython2
J('0 0 PE1.terms 466 [x [PE1.1] dip] times popop')
.. parsed-literal::
233168
A little further analysis renders iteration unnecessary.
========================================================
Consider finding the sum of the positive integers less than or equal to
ten.
.. code:: ipython2
J('[10 9 8 7 6 5 4 3 2 1] sum')
.. parsed-literal::
55
Instead of summing them,
`observe <https://en.wikipedia.org/wiki/File:Animated_proof_for_the_formula_giving_the_sum_of_the_first_integers_1%2B2%2B...%2Bn.gif>`__:
::
10 9 8 7 6
+ 1 2 3 4 5
---- -- -- -- --
11 11 11 11 11
11 * 5 = 55
From the above example we can deduce that the sum of the first N
positive integers is:
::
(N + 1) * N / 2
(The formula also works for odd values of N, I'll leave that to you if
you want to work it out or you can take my word for it.)
.. code:: ipython2
define('F == dup ++ * 2 floordiv')
.. code:: ipython2
V('10 F')
.. parsed-literal::
. 10 F
10 . F
10 . dup ++ * 2 floordiv
10 10 . ++ * 2 floordiv
10 11 . * 2 floordiv
110 . 2 floordiv
110 2 . floordiv
55 .
Generalizing to Blocks of Terms
-------------------------------
We can apply the same reasoning to the PE1 problem.
Between 0 and 990 inclusive there are sixty-six "blocks" of seven terms
each, starting with:
::
[3 5 6 9 10 12 15]
And ending with:
::
[978 980 981 984 985 987 990]
If we reverse one of these two blocks and sum pairs...
.. code:: ipython2
J('[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip')
.. parsed-literal::
[[978 15] [980 12] [981 10] [984 9] [985 6] [987 5] [990 3]]
.. code:: ipython2
J('[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map')
.. parsed-literal::
[993 992 991 993 991 992 993]
(Interesting that the sequence of seven numbers appears again in the
rightmost digit of each term.)
.. code:: ipython2
J('[ 3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map sum')
.. parsed-literal::
6945
Since there are sixty-six blocks and we are pairing them up, there must
be thirty-three pairs, each of which sums to 6945. We also have these
additional unpaired terms between 990 and 1000:
::
993 995 996 999
So we can give the "sum of all the multiples of 3 or 5 below 1000" like
so:
.. code:: ipython2
J('6945 33 * [993 995 996 999] cons sum')
.. parsed-literal::
233168
It's worth noting, I think, that this same reasoning holds for any two
numbers :math:`n` and :math:`m` the multiples of which we hope to sum.
The multiples would have a cycle of differences of length :math:`k` and
so we could compute the sum of :math:`Nk` multiples as above.
The sequence of differences will always be a palidrome. Consider an
interval spanning the least common multiple of :math:`n` and :math:`m`:
::
| | | | | | | |
| | | | |
Here we have 4 and 7, and you can read off the sequence of differences
directly from the diagram: 4 3 1 4 2 2 4 1 3 4.
Geometrically, the actual values of :math:`n` and :math:`m` and their
*lcm* don't matter, the pattern they make will always be symmetrical
around its midpoint. The same reasoning holds for multiples of more than
two numbers.
The Simplest Program
====================
Of course, the simplest joy program for the first Project Euler problem
is just:
::
PE1 == 233168
Fin.

View File

@ -0,0 +1,635 @@
Using ``x`` to Generate Values
==============================
Cf. jp-reprod.html
.. code:: ipython2
from notebook_preamble import J, V, define
Consider the ``x`` combinator:
::
x == dup i
We can apply it to a quoted program consisting of some value ``a`` and
some function ``B``:
::
[a B] x
[a B] a B
Let ``B`` function ``swap`` the ``a`` with the quote and run some
function ``C`` on it to generate a new value ``b``:
::
B == swap [C] dip
[a B] a B
[a B] a swap [C] dip
a [a B] [C] dip
a C [a B]
b [a B]
Now discard the quoted ``a`` with ``rest`` then ``cons`` ``b``:
::
b [a B] rest cons
b [B] cons
[b B]
Altogether, this is the definition of ``B``:
::
B == swap [C] dip rest cons
We can make a generator for the Natural numbers (0, 1, 2, …) by using
``0`` for ``a`` and ``[dup ++]`` for ``[C]``:
::
[0 swap [dup ++] dip rest cons]
Lets try it:
.. code:: ipython2
V('[0 swap [dup ++] dip rest cons] x')
.. parsed-literal::
. [0 swap [dup ++] dip rest cons] x
[0 swap [dup ++] dip rest cons] . x
[0 swap [dup ++] dip rest cons] . 0 swap [dup ++] dip rest cons
[0 swap [dup ++] dip rest cons] 0 . swap [dup ++] dip rest cons
0 [0 swap [dup ++] dip rest cons] . [dup ++] dip rest cons
0 [0 swap [dup ++] dip rest cons] [dup ++] . dip rest cons
0 . dup ++ [0 swap [dup ++] dip rest cons] rest cons
0 0 . ++ [0 swap [dup ++] dip rest cons] rest cons
0 1 . [0 swap [dup ++] dip rest cons] rest cons
0 1 [0 swap [dup ++] dip rest cons] . rest cons
0 1 [swap [dup ++] dip rest cons] . cons
0 [1 swap [dup ++] dip rest cons] .
After one application of ``x`` the quoted program contains ``1`` and
``0`` is below it on the stack.
.. code:: ipython2
J('[0 swap [dup ++] dip rest cons] x x x x x pop')
.. parsed-literal::
0 1 2 3 4
``direco``
----------
.. code:: ipython2
define('direco == dip rest cons')
.. code:: ipython2
V('[0 swap [dup ++] direco] x')
.. parsed-literal::
. [0 swap [dup ++] direco] x
[0 swap [dup ++] direco] . x
[0 swap [dup ++] direco] . 0 swap [dup ++] direco
[0 swap [dup ++] direco] 0 . swap [dup ++] direco
0 [0 swap [dup ++] direco] . [dup ++] direco
0 [0 swap [dup ++] direco] [dup ++] . direco
0 [0 swap [dup ++] direco] [dup ++] . dip rest cons
0 . dup ++ [0 swap [dup ++] direco] rest cons
0 0 . ++ [0 swap [dup ++] direco] rest cons
0 1 . [0 swap [dup ++] direco] rest cons
0 1 [0 swap [dup ++] direco] . rest cons
0 1 [swap [dup ++] direco] . cons
0 [1 swap [dup ++] direco] .
Making Generators
-----------------
We want to define a function that accepts ``a`` and ``[C]`` and builds
our quoted program:
::
a [C] G
-------------------------
[a swap [C] direco]
Working in reverse:
::
[a swap [C] direco] cons
a [swap [C] direco] concat
a [swap] [[C] direco] swap
a [[C] direco] [swap]
a [C] [direco] cons [swap]
Reading from the bottom up:
::
G == [direco] cons [swap] swap concat cons
G == [direco] cons [swap] swoncat cons
.. code:: ipython2
define('G == [direco] cons [swap] swoncat cons')
Lets try it out:
.. code:: ipython2
J('0 [dup ++] G')
.. parsed-literal::
[0 swap [dup ++] direco]
.. code:: ipython2
J('0 [dup ++] G x x x pop')
.. parsed-literal::
0 1 2
Powers of 2
~~~~~~~~~~~
.. code:: ipython2
J('1 [dup 1 <<] G x x x x x x x x x pop')
.. parsed-literal::
1 2 4 8 16 32 64 128 256
``[x] times``
~~~~~~~~~~~~~
If we have one of these quoted programs we can drive it using ``times``
with the ``x`` combinator.
.. code:: ipython2
J('23 [dup ++] G 5 [x] times')
.. parsed-literal::
23 24 25 26 27 [28 swap [dup ++] direco]
Generating Multiples of Three and Five
--------------------------------------
Look at the treatment of the Project Euler Problem One in the
“Developing a Program” notebook and youll see that we might be
interested in generating an endless cycle of:
::
3 2 1 3 1 2 3
To do this we want to encode the numbers as pairs of bits in a single
int:
::
3 2 1 3 1 2 3
0b 11 10 01 11 01 10 11 == 14811
And pick them off by masking with 3 (binary 11) and then shifting the
int right two bits.
.. code:: ipython2
define('PE1.1 == dup [3 &] dip 2 >>')
.. code:: ipython2
V('14811 PE1.1')
.. parsed-literal::
. 14811 PE1.1
14811 . PE1.1
14811 . dup [3 &] dip 2 >>
14811 14811 . [3 &] dip 2 >>
14811 14811 [3 &] . dip 2 >>
14811 . 3 & 14811 2 >>
14811 3 . & 14811 2 >>
3 . 14811 2 >>
3 14811 . 2 >>
3 14811 2 . >>
3 3702 .
If we plug ``14811`` and ``[PE1.1]`` into our generator form…
.. code:: ipython2
J('14811 [PE1.1] G')
.. parsed-literal::
[14811 swap [PE1.1] direco]
…we get a generator that works for seven cycles before it reaches zero:
.. code:: ipython2
J('[14811 swap [PE1.1] direco] 7 [x] times')
.. parsed-literal::
3 2 1 3 1 2 3 [0 swap [PE1.1] direco]
Reset at Zero
~~~~~~~~~~~~~
We need a function that checks if the int has reached zero and resets it
if so.
.. code:: ipython2
define('PE1.1.check == dup [pop 14811] [] branch')
.. code:: ipython2
J('14811 [PE1.1.check PE1.1] G')
.. parsed-literal::
[14811 swap [PE1.1.check PE1.1] direco]
.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times')
.. parsed-literal::
3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 [0 swap [PE1.1.check PE1.1] direco]
(It would be more efficient to reset the int every seven cycles but
thats a little beyond the scope of this article. This solution does
extra work, but not much, and were not using it “in production” as they
say.)
Run 466 times
~~~~~~~~~~~~~
In the PE1 problem we are asked to sum all the multiples of three and
five less than 1000. Its worked out that we need to use all seven
numbers sixty-six times and then four more.
.. code:: ipython2
J('7 66 * 4 +')
.. parsed-literal::
466
If we drive our generator 466 times and sum the stack we get 999.
.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times')
.. parsed-literal::
3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 [57 swap [PE1.1.check PE1.1] direco]
.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum')
.. parsed-literal::
999
Project Euler Problem One
-------------------------
.. code:: ipython2
define('PE1.2 == + dup [+] dip')
Now we can add ``PE1.2`` to the quoted program given to ``G``.
.. code:: ipython2
J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')
.. parsed-literal::
233168
A generator for the Fibonacci Sequence.
---------------------------------------
Consider:
::
[b a F] x
[b a F] b a F
The obvious first thing to do is just add ``b`` and ``a``:
::
[b a F] b a +
[b a F] b+a
From here we want to arrive at:
::
b [b+a b F]
Lets start with ``swons``:
::
[b a F] b+a swons
[b+a b a F]
Considering this quote as a stack:
::
F a b b+a
We want to get it to:
::
F b b+a b
So:
::
F a b b+a popdd over
F b b+a b
And therefore:
::
[b+a b a F] [popdd over] infra
[b b+a b F]
But we can just use ``cons`` to carry ``b+a`` into the quote:
::
[b a F] b+a [popdd over] cons infra
[b a F] [b+a popdd over] infra
[b b+a b F]
Lastly:
::
[b b+a b F] uncons
b [b+a b F]
Putting it all together:
::
F == + [popdd over] cons infra uncons
fib_gen == [1 1 F]
.. code:: ipython2
define('fib == + [popdd over] cons infra uncons')
.. code:: ipython2
define('fib_gen == [1 1 fib]')
.. code:: ipython2
J('fib_gen 10 [x] times')
.. parsed-literal::
1 2 3 5 8 13 21 34 55 89 [144 89 fib]
Project Euler Problem Two
-------------------------
By considering the terms in the Fibonacci sequence whose values do
not exceed four million, find the sum of the even-valued terms.
Now that we have a generator for the Fibonacci sequence, we need a
function that adds a term in the sequence to a sum if it is even, and
``pop``\ s it otherwise.
.. code:: ipython2
define('PE2.1 == dup 2 % [+] [pop] branch')
And a predicate function that detects when the terms in the series
“exceed four million”.
.. code:: ipython2
define('>4M == 4000000 >')
Now its straightforward to define ``PE2`` as a recursive function that
generates terms in the Fibonacci sequence until they exceed four million
and sums the even ones.
.. code:: ipython2
define('PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec')
.. code:: ipython2
J('PE2')
.. parsed-literal::
4613732
Heres the collected program definitions:
::
fib == + swons [popdd over] infra uncons
fib_gen == [1 1 fib]
even == dup 2 %
>4M == 4000000 >
PE2.1 == even [+] [pop] branch
PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
Even-valued Fibonacci Terms
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using ``o`` for odd and ``e`` for even:
::
o + o = e
e + e = e
o + e = o
So the Fibonacci sequence considered in terms of just parity would be:
::
o o e o o e o o e o o e o o e o o e
1 1 2 3 5 8 . . .
Every third term is even.
.. code:: ipython2
J('[1 0 fib] x x x') # To start the sequence with 1 1 2 3 instead of 1 2 3.
.. parsed-literal::
1 1 2 [3 2 fib]
Drive the generator three times and ``popop`` the two odd terms.
.. code:: ipython2
J('[1 0 fib] x x x [popop] dipd')
.. parsed-literal::
2 [3 2 fib]
.. code:: ipython2
define('PE2.2 == x x x [popop] dipd')
.. code:: ipython2
J('[1 0 fib] 10 [PE2.2] times')
.. parsed-literal::
2 8 34 144 610 2584 10946 46368 196418 832040 [1346269 832040 fib]
Replace ``x`` with our new driver function ``PE2.2`` and start our
``fib`` generator at ``1 0``.
.. code:: ipython2
J('0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec')
.. parsed-literal::
4613732
How to compile these?
---------------------
You would probably start with a special version of ``G``, and perhaps
modifications to the default ``x``?
An Interesting Variation
------------------------
.. code:: ipython2
define('codireco == cons dip rest cons')
.. code:: ipython2
V('[0 [dup ++] codireco] x')
.. parsed-literal::
. [0 [dup ++] codireco] x
[0 [dup ++] codireco] . x
[0 [dup ++] codireco] . 0 [dup ++] codireco
[0 [dup ++] codireco] 0 . [dup ++] codireco
[0 [dup ++] codireco] 0 [dup ++] . codireco
[0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons
[0 [dup ++] codireco] [0 dup ++] . dip rest cons
. 0 dup ++ [0 [dup ++] codireco] rest cons
0 . dup ++ [0 [dup ++] codireco] rest cons
0 0 . ++ [0 [dup ++] codireco] rest cons
0 1 . [0 [dup ++] codireco] rest cons
0 1 [0 [dup ++] codireco] . rest cons
0 1 [[dup ++] codireco] . cons
0 [1 [dup ++] codireco] .
.. code:: ipython2
define('G == [codireco] cons cons')
.. code:: ipython2
J('230 [dup ++] G 5 [x] times pop')
.. parsed-literal::
230 231 232 233 234

View File

@ -0,0 +1,335 @@
*******************
Thun: Joy in Python
*******************
This implementation is meant as a tool for exploring the programming
model and method of Joy. Python seems like a great implementation
language for Joy for several reasons.
* We can lean on the Python immutable types for our basic semantics and types: ints, floats, strings, and tuples, which enforces functional purity.
* We get garbage collection for free.
* Compilation via Cython.
* Python is a "glue language" with loads of libraries which we can wrap in Joy functions.
`Read-Eval-Print Loop (REPL) <https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop>`__
====================================================================================================
The main way to interact with the Joy interpreter is through a simple
`REPL <https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop>`__
that you start by running the package:
::
$ python3 -m joy
Thun - Copyright © 2017 Simon Forman
This program comes with ABSOLUTELY NO WARRANTY; for details type "warranty".
This is free software, and you are welcome to redistribute it
under certain conditions; type "sharing" for details.
Type "words" to see a list of all words, and "[<name>] help" to print the
docs for a word.
<-top
joy? _
The ``<-top`` marker points to the top of the (initially empty) stack.
You can enter Joy notation at the prompt and a :doc:`trace of evaluation <../pretty>` will
be printed followed by the stack and prompt again::
joy? 23 sqr 18 +
547 <-top
joy?
There is a `trace` combinator::
joy? 23 [sqr 18 +] trace
23 . sqr 18 +
23 . dup mul 18 +
23 23 . mul 18 +
529 . 18 +
529 18 . +
547 .
547 <-top
joy?
The Stack
=============
In Joy, in addition to the types Boolean, integer, float, and string,
there is a :doc:`single sequence type <../stack>` represented by enclosing a sequence of
terms in brackets ``[...]``. This sequence type is used to represent
both the stack and the expression. It is a `cons
list <https://en.wikipedia.org/wiki/Cons#Lists>`__ made from Python
tuples.
Purely Functional Datastructures
=================================
Because Joy stacks are made out of Python tuples they are immutable, as are the other Python types we "borrow" for Joy, so all Joy datastructures are `purely functional <https://en.wikipedia.org/wiki/Purely_functional_data_structure>`__.
The ``joy()`` function
=======================
An Interpreter
~~~~~~~~~~~~~~~~~
The ``joy()`` interpreter function is extrememly simple. It accepts a stack, an
expression, and a dictionary, and it iterates through the expression
putting values onto the stack and delegating execution to functions which it
looks up in the dictionary.
`Continuation-Passing Style <https://en.wikipedia.org/wiki/Continuation-passing_style>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
One day I thought, What happens if you rewrite Joy to use
`CPS <https://en.wikipedia.org/wiki/Continuation-passing_style>`__? I
made all the functions accept and return the expression as well as the
stack and found that all the combinators could be rewritten to work by
modifying the expression rather than making recursive calls to the
``joy()`` function.
View function
~~~~~~~~~~~~~
The ``joy()`` function accepts an optional ``viewer`` argument that
is a function which it calls on
each iteration passing the current stack and expression just before
evaluation. This can be used for tracing, breakpoints, retrying after
exceptions, or interrupting an evaluation and saving to disk or sending
over the network to resume later. The stack and expression together
contain all the state of the computation at each step.
The ``TracePrinter``.
~~~~~~~~~~~~~~~~~~~~~
A ``viewer`` records each step of the evaluation of a Joy program. The
``TracePrinter`` has a facility for printing out a trace of the
evaluation, one line per step. Each step is aligned to the current
interpreter position, signified by a period separating the stack on the
left from the pending expression ("continuation") on the right.
Parser
======
The parser is extremely simple. The undocumented ``re.Scanner`` class
does the tokenizing and then the parser builds the tuple
structure out of the tokens. There's no Abstract Syntax Tree or anything
like that.
Symbols
~~~~~~~~~~~~~
TODO: Symbols are just a string subclass; used by the parser to represent function names and by the interpreter to look up functions in the dictionary. N.B.: Symbols are not looked up at parse-time. You *could* define recursive functions, er, recusively, without ``genrec`` or other recursion combinators ``foo == ... foo ...`` but don't do that.
Token Regular Expressions
~~~~~~~~~~~~~~~~~~~~~~~~~
::
123 1.2 'single quotes' "double quotes" function
TBD (look in the :module: joy.parser module.)
Examples
~~~~~~~~~~~
.. code:: ipython2
joy.parser.text_to_expression('1 2 3 4 5') # A simple sequence.
.. parsed-literal::
(1, (2, (3, (4, (5, ())))))
.. code:: ipython2
joy.parser.text_to_expression('[1 2 3] 4 5') # Three items, the first is a list with three items
.. parsed-literal::
((1, (2, (3, ()))), (4, (5, ())))
.. code:: ipython2
joy.parser.text_to_expression('1 23 ["four" [-5.0] cons] 8888') # A mixed bag. cons is
# a Symbol, no lookup at
# parse-time. Haiku docs.
.. parsed-literal::
(1, (23, (('four', ((-5.0, ()), (cons, ()))), (8888, ()))))
.. code:: ipython2
joy.parser.text_to_expression('[][][][][]') # Five empty lists.
.. parsed-literal::
((), ((), ((), ((), ((), ())))))
.. code:: ipython2
joy.parser.text_to_expression('[[[[[]]]]]') # Five nested lists.
.. parsed-literal::
((((((), ()), ()), ()), ()), ())
Library
=======
The Joy library of functions (aka commands, or "words" after Forth
usage) encapsulates all the actual functionality (no pun intended) of
the Joy system. There are simple functions such as addition ``add`` (or
``+``, the library module supports aliases), and combinators which
provide control-flow and higher-order operations.
Many of the functions are defined in Python, like ``dip``:
.. code:: ipython2
print inspect.getsource(joy.library.dip)
.. parsed-literal::
def dip(stack, expression, dictionary):
(quote, (x, stack)) = stack
expression = x, expression
return stack, concat(quote, expression), dictionary
Some functions are defined in equations in terms of other functions.
When the interpreter executes a definition function that function just
pushes its body expression onto the pending expression (the
continuation) and returns control to the interpreter.
.. code:: ipython2
print joy.library.definitions
.. parsed-literal::
second == rest first
third == rest rest first
product == 1 swap [*] step
swons == swap cons
swoncat == swap concat
flatten == [] swap [concat] step
unit == [] cons
quoted == [unit] dip
unquoted == [i] dip
enstacken == stack [clear] dip
disenstacken == ? [uncons ?] loop pop
? == dup truthy
dinfrirst == dip infra first
nullary == [stack] dinfrirst
unary == [stack [pop] dip] dinfrirst
binary == [stack [popop] dip] dinfrirst
ternary == [stack [popop pop] dip] dinfrirst
pam == [i] map
run == [] swap infra
sqr == dup mul
size == 0 swap [pop ++] step
cleave == [i] app2 [popd] dip
average == [sum 1.0 *] [size] cleave /
gcd == 1 [tuck modulus dup 0 >] loop pop
least_fraction == dup [gcd] infra [div] concat map
*fraction == [uncons] dip uncons [swap] dip concat [*] infra [*] dip cons
*fraction0 == concat [[swap] dip * [*] dip] infra
down_to_zero == [0 >] [dup --] while
range_to_zero == unit [down_to_zero] infra
anamorphism == [pop []] swap [dip swons] genrec
range == [0 <=] [1 - dup] anamorphism
while == swap [nullary] cons dup dipd concat loop
dudipd == dup dipd
primrec == [i] genrec
Currently, there's no function to add new definitions to the dictionary
from "within" Joy code itself. Adding new definitions remains a
meta-interpreter action. You have to do it yourself, in Python, and wash
your hands afterward.
It would be simple enough to define one, but it would open the door to
*name binding* and break the idea that all state is captured in the
stack and expression. There's an implicit *standard dictionary* that
defines the actual semantics of the syntactic stack and expression
datastructures (which only contain symbols, not the actual functions.
Pickle some and see for yourself.)
"There should be only one."
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Which brings me to talking about one of my hopes and dreams for this
notation: "There should be only one." What I mean is that there should
be one universal standard dictionary of commands, and all bespoke work
done in a UI for purposes takes place by direct interaction and macros.
There would be a *Grand Refactoring* biannually (two years, not six
months, that's semi-annually) where any new definitions factored out of
the usage and macros of the previous time, along with new algorithms and
such, were entered into the dictionary and posted to e.g. IPFS.
Code should not burgeon wildly, as it does today. The variety of code
should map more-or-less to the well-factored variety of human
computably-solvable problems. There shouldn't be dozens of chat apps, JS
frameworks, programming languages. It's a waste of time, a `fractal
"thundering herd"
attack <https://en.wikipedia.org/wiki/Thundering_herd_problem>`__ on
human mentality.
Literary Code Library
~~~~~~~~~~~~~~~~~~~~~
If you read over the other notebooks you'll see that developing code in
Joy is a lot like doing simple mathematics, and the descriptions of the
code resemble math papers. The code also works the first time, no bugs.
If you have any experience programming at all, you are probably
skeptical, as I was, but it seems to work: deriving code mathematically
seems to lead to fewer errors.
But my point now is that this great ratio of textual explanation to wind
up with code that consists of a few equations and could fit on an index
card is highly desirable. Less code has fewer errors. The structure of
Joy engenders a kind of thinking that seems to be very effective for
developing structured processes.
There seems to be an elegance and power to the notation.

View File

@ -0,0 +1,257 @@
`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
=====================================================================
Let's use the Newton-Raphson method for finding the root of an equation
to write a function that can compute the square root of a number.
Cf. `"Why Functional Programming Matters" by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
.. code:: ipython3
from notebook_preamble import J, V, define
A Generator for Approximations
------------------------------
To make a generator that generates successive approximations lets start
by assuming an initial approximation and then derive the function that
computes the next approximation:
::
a F
---------
a'
A Function to Compute the Next Approximation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the equation for computing the next approximate value of the
square root:
:math:`a_{i+1} = \frac{(a_i+\frac{n}{a_i})}{2}`
::
a n over / + 2 /
a n a / + 2 /
a n/a + 2 /
a+n/a 2 /
(a+n/a)/2
The function we want has the argument ``n`` in it:
::
F == n over / + 2 /
Make it into a Generator
~~~~~~~~~~~~~~~~~~~~~~~~
Our generator would be created by:
::
a [dup F] make_generator
With n as part of the function F, but n is the input to the sqrt
function were writing. If we let 1 be the initial approximation:
::
1 n 1 / + 2 /
1 n/1 + 2 /
1 n + 2 /
n+1 2 /
(n+1)/2
The generator can be written as:
::
23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
1 23 [over / + 2 /] cons [dup] swoncat make_generator
1 [23 over / + 2 /] [dup] swoncat make_generator
1 [dup 23 over / + 2 /] make_generator
.. code:: ipython3
define('gsra 1 swap [over / + 2 /] cons [dup] swoncat make_generator')
.. code:: ipython3
J('23 gsra')
.. parsed-literal::
[1 [dup 23 over / + 2 /] codireco]
Let's drive the generator a few time (with the ``x`` combinator) and
square the approximation to see how well it works...
.. code:: ipython3
J('23 gsra 6 [x popd] times first sqr')
.. parsed-literal::
23.0000000001585
Finding Consecutive Approximations within a Tolerance
-----------------------------------------------------
From `"Why Functional Programming Matters" by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__:
The remainder of a square root finder is a function *within*, which
takes a tolerance and a list of approximations and looks down the
list for two successive approximations that differ by no more than
the given tolerance.
(And note that by “list” he means a lazily-evaluated list.)
Using the *output* ``[a G]`` of the above generator for square root
approximations, and further assuming that the first term a has been
generated already and epsilon ε is handy on the stack...
::
a [b G] ε within
---------------------- a b - abs ε <=
b
a [b G] ε within
---------------------- a b - abs ε >
b [c G] ε within
Predicate
~~~~~~~~~
::
a [b G] ε [first - abs] dip <=
a [b G] first - abs ε <=
a b - abs ε <=
a-b abs ε <=
abs(a-b) ε <=
(abs(a-b)<=ε)
.. code:: ipython3
define('_within_P [first - abs] dip <=')
Base-Case
~~~~~~~~~
::
a [b G] ε roll< popop first
[b G] ε a popop first
[b G] first
b
.. code:: ipython3
define('_within_B roll< popop first')
Recur
~~~~~
::
a [b G] ε R0 [within] R1
1. Discard a.
2. Use ``x`` combinator to generate next term from ``G``.
3. Run ``within`` with ``i`` (it is a "tail-recursive" function.)
Pretty straightforward:
::
a [b G] ε R0 [within] R1
a [b G] ε [popd x] dip [within] i
a [b G] popd x ε [within] i
[b G] x ε [within] i
b [c G] ε [within] i
b [c G] ε within
b [c G] ε within
.. code:: ipython3
define('_within_R [popd x] dip')
Setting up
~~~~~~~~~~
The recursive function we have defined so far needs a slight preamble:
``x`` to prime the generator and the epsilon value to use:
::
[a G] x ε ...
a [b G] ε ...
.. code:: ipython3
define('within x 0.000000001 [_within_P] [_within_B] [_within_R] tailrec')
define('sqrt gsra within')
Try it out...
.. code:: ipython3
J('36 sqrt')
.. parsed-literal::
6.0
.. code:: ipython3
J('23 sqrt')
.. parsed-literal::
4.795831523312719
Check it.
.. code:: ipython3
4.795831523312719**2
.. parsed-literal::
22.999999999999996
.. code:: ipython3
from math import sqrt
sqrt(23)
.. parsed-literal::
4.795831523312719

View File

@ -0,0 +1,22 @@
**************
No Updates
**************
DRAFT
1. Joy doesn't need to change.
A. The interpreter doesn't need to change, ``viewer`` function can customize mainloop. Or use a sub-interpreter (Joy in Joy.) The base interpreter remains static.
B. Once a function has been named and defined *never change that name*. It's just not allowed. If you need to change a function ``foo`` you have to call it ``foo_II`` or something. Once a function (name mapped to behavior) is released to the public *that's it*, it's done.
C. The language evolves by adding new definitions and refactoring, always choosing new names for new functions.
2. Following `Semantic Versioning`_ there will never be a version 2.0.
A. `Major version must be incremented if any backwards incompatible changes are introduced to the public API. <https://semver.org/#spec-item-8>`__
B. We never implement any backwards incompatible changes, so...
C. We could see e.g. Thun version 1.273.3!
.. _Semantic Versioning: https://semver.org

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
.. code:: ipython2
from notebook_preamble import J, V, define
`Quadratic formula <https://en.wikipedia.org/wiki/Quadratic_formula>`__
=======================================================================
Cf.
`jp-quadratic.html <http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html>`__
::
-b ± sqrt(b^2 - 4 * a * c)
--------------------------------
2 * a
:math:`\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}`
Write a straightforward program with variable names.
----------------------------------------------------
This math translates to Joy code in a straightforward manner. We are
going to use named variables to keep track of the arguments, then write
a definition without them.
``-b``
~~~~~~
::
b neg
``sqrt(b^2 - 4 * a * c)``
~~~~~~~~~~~~~~~~~~~~~~~~~
::
b sqr 4 a c * * - sqrt
``/2a``
~~~~~~~
::
a 2 * /
``±``
~~~~~
There is a function ``pm`` that accepts two values on the stack and
replaces them with their sum and difference.
::
pm == [+] [-] cleave popdd
Putting Them Together
~~~~~~~~~~~~~~~~~~~~~
::
b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
We use ``app2`` to compute both roots by using a quoted program
``[2a /]`` built with ``cons``.
Derive a definition.
--------------------
Working backwards we use ``dip`` and ``dipd`` to extract the code from
the variables:
::
b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
b [neg] dupdip sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
b a c [[neg] dupdip sqr 4] dipd * * - sqrt pm a 2 * [/] cons app2
b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
The three arguments are to the left, so we can “chop off” everything to
the right and say its the definition of the ``quadratic`` function:
.. code:: ipython2
define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
Lets try it out:
.. code:: ipython2
J('3 1 1 quadratic')
.. parsed-literal::
-0.3819660112501051 -2.618033988749895
If you look at the Joy evaluation trace you can see that the first few
lines are the ``dip`` and ``dipd`` combinators building the main program
by incorporating the values on the stack. Then that program runs and you
get the results. This is pretty typical of Joy code.
.. code:: ipython2
V('-5 1 4 quadratic')
.. parsed-literal::
. -5 1 4 quadratic
-5 . 1 4 quadratic
-5 1 . 4 quadratic
-5 1 4 . quadratic
-5 1 4 . over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
-5 1 4 1 . [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
-5 1 4 1 [[[neg] dupdip sqr 4] dipd * * - sqrt pm] . dip 2 * [/] cons app2
-5 1 4 . [[neg] dupdip sqr 4] dipd * * - sqrt pm 1 2 * [/] cons app2
-5 1 4 [[neg] dupdip sqr 4] . dipd * * - sqrt pm 1 2 * [/] cons app2
-5 . [neg] dupdip sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2
-5 [neg] . dupdip sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2
-5 . neg -5 sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2
5 . -5 sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2
5 -5 . sqr 4 1 4 * * - sqrt pm 1 2 * [/] cons app2
5 -5 . dup mul 4 1 4 * * - sqrt pm 1 2 * [/] cons app2
5 -5 -5 . mul 4 1 4 * * - sqrt pm 1 2 * [/] cons app2
5 25 . 4 1 4 * * - sqrt pm 1 2 * [/] cons app2
5 25 4 . 1 4 * * - sqrt pm 1 2 * [/] cons app2
5 25 4 1 . 4 * * - sqrt pm 1 2 * [/] cons app2
5 25 4 1 4 . * * - sqrt pm 1 2 * [/] cons app2
5 25 4 4 . * - sqrt pm 1 2 * [/] cons app2
5 25 16 . - sqrt pm 1 2 * [/] cons app2
5 9 . sqrt pm 1 2 * [/] cons app2
5 3.0 . pm 1 2 * [/] cons app2
8.0 2.0 . 1 2 * [/] cons app2
8.0 2.0 1 . 2 * [/] cons app2
8.0 2.0 1 2 . * [/] cons app2
8.0 2.0 2 . [/] cons app2
8.0 2.0 2 [/] . cons app2
8.0 2.0 [2 /] . app2
[8.0] [2 /] . infra first [2.0] [2 /] infra first
8.0 . 2 / [] swaack first [2.0] [2 /] infra first
8.0 2 . / [] swaack first [2.0] [2 /] infra first
4.0 . [] swaack first [2.0] [2 /] infra first
4.0 [] . swaack first [2.0] [2 /] infra first
[4.0] . first [2.0] [2 /] infra first
4.0 . [2.0] [2 /] infra first
4.0 [2.0] . [2 /] infra first
4.0 [2.0] [2 /] . infra first
2.0 . 2 / [4.0] swaack first
2.0 2 . / [4.0] swaack first
1.0 . [4.0] swaack first
1.0 [4.0] . swaack first
4.0 [1.0] . first
4.0 1.0 .

View File

@ -0,0 +1,690 @@
.. code:: ipython2
from notebook_preamble import D, DefinitionWrapper, J, V, define
Recursion Combinators
=====================
This article describes the ``genrec`` combinator, how to use it, and
several generic specializations.
::
[if] [then] [rec1] [rec2] genrec
---------------------------------------------------------------------
[if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun:
“The genrec combinator takes four program parameters in addition to
whatever data parameters it needs. Fourth from the top is an if-part,
followed by a then-part. If the if-part yields true, then the
then-part is executed and the combinator terminates. The other two
parameters are the rec1-part and the rec2-part. If the if-part yields
false, the rec1-part is executed. Following that the four program
parameters and the combinator are again pushed onto the stack bundled
up in a quoted form. Then the rec2-part is executed, where it will
find the bundled form. Typically it will then execute the bundled
form, either with i or with app2, or some other combinator.”
Designing Recursive Functions
-----------------------------
The way to design one of these is to fix your base case and test and
then treat ``R1`` and ``R2`` as an else-part “sandwiching” a quotation
of the whole function.
For example, given a (general recursive) function ``F``:
::
F == [I] [T] [R1] [R2] genrec
== [I] [T] [R1 [F] R2] ifte
If the ``[I]`` predicate is false you must derive ``R1`` and ``R2``
from:
::
... R1 [F] R2
Set the stack arguments in front and figure out what ``R1`` and ``R2``
have to do to apply the quoted ``[F]`` in the proper way.
Primitive Recursive Functions
-----------------------------
Primitive recursive functions are those where ``R2 == i``.
::
P == [I] [T] [R] primrec
== [I] [T] [R [P] i] ifte
== [I] [T] [R P] ifte
`Hylomorphism <https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29>`__
------------------------------------------------------------------------------------
A
`hylomorphism <https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29>`__
is a recursive function ``H :: A -> C`` that converts a value of type
``A`` into a value of type ``C`` by means of:
- A generator ``G :: A -> (B, A)``
- A combiner ``F :: (B, C) -> C``
- A predicate ``P :: A -> Bool`` to detect the base case
- A base case value ``c :: C``
- Recursive calls (zero or more); it has a “call stack in the form of a
cons list”.
It may be helpful to see this function implemented in imperative Python
code.
.. code:: ipython2
def hylomorphism(c, F, P, G):
'''Return a hylomorphism function H.'''
def H(a):
if P(a):
result = c
else:
b, aa = G(a)
result = F(b, H(aa)) # b is stored in the stack frame during recursive call to H().
return result
return H
Cf. `“Bananas, Lenses, & Barbed
Wire” <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
Note that during evaluation of ``H()`` the intermediate ``b`` values are
stored in the Python call stack. This is what is meant by “call stack in
the form of a cons list”.
Hylomorphism in Joy
-------------------
We can define a combinator ``hylomorphism`` that will make a
hylomorphism combinator ``H`` from constituent parts.
::
H == [P] c [G] [F] hylomorphism
The function ``H`` is recursive, so we start with ``ifte`` and set the
else-part to some function ``J`` that will contain a quoted copy of
``H``. (The then-part just discards the leftover ``a`` and replaces it
with the base case value ``c``.)
::
H == [P] [pop c] [J] ifte
The else-part ``J`` gets just the argument ``a`` on the stack.
::
a J
a G The first thing to do is use the generator G
aa b which produces b and a new aa
aa b [H] dip we recur with H on the new aa
aa H b F and run F on the result.
This gives us a definition for ``J``.
::
J == G [H] dip F
Plug it in and convert to genrec.
::
H == [P] [pop c] [G [H] dip F] ifte
H == [P] [pop c] [G] [dip F] genrec
This is the form of a hylomorphism in Joy, which nicely illustrates that
it is a simple specialization of the general recursion combinator.
::
H == [P] c [G] [F] hylomorphism == [P] [pop c] [G] [dip F] genrec
Derivation of ``hylomorphism`` combinator
-----------------------------------------
Now we just need to derive a definition that builds the ``genrec``
arguments out of the pieces given to the ``hylomorphism`` combinator.
::
[P] c [G] [F] hylomorphism
------------------------------------------
[P] [pop c] [G] [dip F] genrec
Working in reverse:
- Use ``swoncat`` twice to decouple ``[c]`` and ``[F]``.
- Use ``unit`` to dequote ``c``.
- Use ``dipd`` to untangle ``[unit [pop] swoncat]`` from the givens.
So:
::
H == [P] [pop c] [G] [dip F] genrec
[P] [c] [pop] swoncat [G] [F] [dip] swoncat genrec
[P] c unit [pop] swoncat [G] [F] [dip] swoncat genrec
[P] c [G] [F] [unit [pop] swoncat] dipd [dip] swoncat genrec
At this point all of the arguments (givens) to the hylomorphism are to
the left so we have a definition for ``hylomorphism``:
::
hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
.. code:: ipython2
define('hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec')
Example: Finding `Triangular Numbers <https://en.wikipedia.org/wiki/Triangular_number>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Lets write a function that, given a positive integer, returns the sum
of all positive integers less than that one. (In this case the types
``A``, ``B`` and ``C`` are all ``int``.)
To sum a range of integers from 0 to *n* - 1:
- ``[P]`` is ``[1 <=]``
- ``c`` is ``0``
- ``[G]`` is ``[-- dup]``
- ``[F]`` is ``[+]``
.. code:: ipython2
define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')
Lets try it:
.. code:: ipython2
J('5 triangular_number')
.. parsed-literal::
10
.. code:: ipython2
J('[0 1 2 3 4 5 6] [triangular_number] map')
.. parsed-literal::
[0 0 1 3 6 10 15]
Four Specializations
--------------------
There are at least four kinds of recursive combinator, depending on two
choices. The first choice is whether the combiner function ``F`` should
be evaluated during the recursion or pushed into the pending expression
to be “collapsed” at the end. The second choice is whether the combiner
needs to operate on the current value of the datastructure or the
generators output, in other words, whether ``F`` or ``G`` should run
first in the recursive branch.
::
H1 == [P] [pop c] [G ] [dip F] genrec
H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
The working of the generator function ``G`` differs slightly for each.
Consider the recursive branches:
::
... a G [H1] dip F w/ a G == a b
... c a G [F] dip H2 a G == b a
... a [G] dupdip [H3] dip F a G == a
... c a [F] dupdip G H4 a G == a
The following four sections illustrate how these work, omitting the
predicate evaluation.
``H1``
~~~~~~
::
H1 == [P] [pop c] [G] [dip F] genrec
Iterate n times.
::
... a G [H1] dip F
... a b [H1] dip F
... a H1 b F
... a G [H1] dip F b F
... a″ b [H1] dip F b F
... a″ H1 b F b F
... a″ G [H1] dip F b F b F
... a‴ b″ [H1] dip F b F b F
... a‴ H1 b″ F b F b F
... a‴ pop c b″ F b F b F
... c b″ F b F b F
... d b F b F
... d b F
... d″
This form builds up a pending expression (continuation) that contains
the intermediate results along with the pending combiner functions. When
the base case is reached the last term is replaced by the identity value
``c`` and the continuation “collapses” into the final result using the
combiner ``F``.
``H2``
~~~~~~
When you can start with the identity value ``c`` on the stack and the
combiner ``F`` can operate as you go using the intermediate results
immediately rather than queuing them up, use this form. An important
difference is that the generator function must return its results in the
reverse order.
::
H2 == c swap [P] [pop] [G [F] dip] primrec
... c a G [F] dip H2
... c b a [F] dip H2
... c b F a H2
... d a H2
... d a G [F] dip H2
... d b a″ [F] dip H2
... d b F a″ H2
... d a″ H2
... d a″ G [F] dip H2
... d b″ a‴ [F] dip H2
... d b″ F a‴ H2
... d″ a‴ H2
... d″ a‴ pop
... d″
``H3``
~~~~~~
If you examine the traces above youll see that the combiner ``F`` only
gets to operate on the results of ``G``, it never “sees” the first value
``a``. If the combiner and the generator both need to work on the
current value then ``dup`` must be used, and the generator must produce
one item instead of two (the b is instead the duplicate of a.)
::
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
... a [G] dupdip [H3] dip F
... a G a [H3] dip F
... a a [H3] dip F
... a H3 a F
... a [G] dupdip [H3] dip F a F
... a G a [H3] dip F a F
... a″ a [H3] dip F a F
... a″ H3 a F a F
... a″ [G] dupdip [H3] dip F a F a F
... a″ G a″ [H3] dip F a F a F
... a‴ a″ [H3] dip F a F a F
... a‴ H3 a″ F a F a F
... a‴ pop c a″ F a F a F
... c a″ F a F a F
... d a F a F
... d a F
... d″
``H4``
~~~~~~
And, last but not least, if you can combine as you go, starting with
``c``, and the combiner ``F`` needs to work on the current item, this is
the form:
::
H4 == c swap [P] [pop] [[F] dupdip G] primrec
... c a [F] dupdip G H4
... c a F a G H4
... d a G H4
... d a H4
... d a [F] dupdip G H4
... d a F a G H4
... d a G H4
... d a″ H4
... d a″ [F] dupdip G H4
... d a″ F a″ G H4
... d″ a″ G H4
... d″ a‴ H4
... d″ a‴ pop
... d″
Anamorphism
-----------
An anamorphism can be defined as a hylomorphism that uses ``[]`` for
``c`` and ``swons`` for ``F``. An anamorphic function builds a list of
values.
::
A == [P] [] [G] [swons] hylomorphism
``range`` et. al. An example of an anamorphism is the ``range`` function which generates the list of integers from 0 to *n* - 1 given *n*.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each of the above variations can be used to make four slightly different
``range`` functions.
``range`` with ``H1``
^^^^^^^^^^^^^^^^^^^^^
::
H1 == [P] [pop c] [G] [dip F] genrec
== [0 <=] [pop []] [-- dup] [dip swons] genrec
.. code:: ipython2
define('range == [0 <=] [] [-- dup] [swons] hylomorphism')
.. code:: ipython2
J('5 range')
.. parsed-literal::
[4 3 2 1 0]
``range`` with ``H2``
^^^^^^^^^^^^^^^^^^^^^
::
H2 == c swap [P] [pop] [G [F] dip] primrec
== [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
.. code:: ipython2
define('range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec')
.. code:: ipython2
J('5 range_reverse')
.. parsed-literal::
[0 1 2 3 4]
``range`` with ``H3``
^^^^^^^^^^^^^^^^^^^^^
::
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
== [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
.. code:: ipython2
define('ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec')
.. code:: ipython2
J('5 ranger')
.. parsed-literal::
[5 4 3 2 1]
``range`` with ``H4``
^^^^^^^^^^^^^^^^^^^^^
::
H4 == c swap [P] [pop] [[F] dupdip G ] primrec
== [] swap [0 <=] [pop] [[swons] dupdip --] primrec
.. code:: ipython2
define('ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec')
.. code:: ipython2
J('5 ranger_reverse')
.. parsed-literal::
[1 2 3 4 5]
Hopefully this illustrates the workings of the variations. For more
insight you can run the cells using the ``V()`` function instead of the
``J()`` function to get a trace of the Joy evaluation.
Catamorphism
------------
A catamorphism can be defined as a hylomorphism that uses
``[uncons swap]`` for ``[G]`` and ``[[] =]`` (or just ``[not]``) for the
predicate ``[P]``. A catamorphic function tears down a list term-by-term
and makes some new value.
::
C == [not] c [uncons swap] [F] hylomorphism
.. code:: ipython2
define('swuncons == uncons swap') # Awkward name.
An example of a catamorphism is the sum function.
::
sum == [not] 0 [swuncons] [+] hylomorphism
.. code:: ipython2
define('sum == [not] 0 [swuncons] [+] hylomorphism')
.. code:: ipython2
J('[5 4 3 2 1] sum')
.. parsed-literal::
15
The ``step`` combinator
~~~~~~~~~~~~~~~~~~~~~~~
The ``step`` combinator will usually be better to use than
``catamorphism``.
.. code:: ipython2
J('[step] help')
.. parsed-literal::
Run a quoted program on each item in a sequence.
::
... [] [Q] . step
-----------------------
... .
... [a] [Q] . step
------------------------
... a . Q
... [a b c] [Q] . step
----------------------------------------
... a . Q [b c] [Q] step
The step combinator executes the quotation on each member of the list
on top of the stack.
.. code:: ipython2
define('sum == 0 swap [+] step')
.. code:: ipython2
J('[5 4 3 2 1] sum')
.. parsed-literal::
15
Example: Factorial Function
---------------------------
For the Factorial function:
::
H4 == c swap [P] [pop] [[F] dupdip G] primrec
With:
::
c == 1
F == *
G == --
P == 1 <=
.. code:: ipython2
define('factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec')
.. code:: ipython2
J('5 factorial')
.. parsed-literal::
120
Example: ``tails``
------------------
An example of a paramorphism for lists given in the `“Bananas…”
paper <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
is ``tails`` which returns the list of “tails” of a list.
::
[1 2 3] tails
--------------------
[[] [3] [2 3]]
We can build as we go, and we want ``F`` to run after ``G``, so we use
pattern ``H2``:
::
H2 == c swap [P] [pop] [G [F] dip] primrec
We would use:
::
c == []
F == swons
G == rest dup
P == not
.. code:: ipython2
define('tails == [] swap [not] [pop] [rest dup [swons] dip] primrec')
.. code:: ipython2
J('[1 2 3] tails')
.. parsed-literal::
[[] [3] [2 3]]
Conclusion: Patterns of Recursion
---------------------------------
Our story so far…
Hylo-, Ana-, Cata-
~~~~~~~~~~~~~~~~~~
::
H == [P ] [pop c ] [G ] [dip F ] genrec
A == [P ] [pop []] [G ] [dip swap cons] genrec
C == [not] [pop c ] [uncons swap] [dip F ] genrec
Para-, ?-, ?-
~~~~~~~~~~~~~
::
P == c swap [P ] [pop] [[F ] dupdip G ] primrec
? == [] swap [P ] [pop] [[swap cons] dupdip G ] primrec
? == c swap [not] [pop] [[F ] dupdip uncons swap] primrec
Appendix: Fun with Symbols
--------------------------
::
|[ (c, F), (G, P) ]| == (|c, F|) • [(G, P)]
`“Bananas, Lenses, & Barbed
Wire” <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
::
(|...|) [(...)] [<...>]
I think they are having slightly too much fun with the symbols. However,
“Too much is always better than not enough.”

View File

@ -0,0 +1,147 @@
Replacing Functions in the Dictionary
=====================================
For now, there is no way to define new functions from within the Joy
language. All functions (and the interpreter) all accept and return a
dictionary parameter (in addition to the stack and expression) so that
we can implement e.g. a function that adds new functions to the
dictionary. However, theres no function that does that. Adding a new
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.
.. code:: ipython2
from notebook_preamble import D, J, V
A long trace
------------
.. code:: ipython2
V('[23 18] average')
.. parsed-literal::
. [23 18] average
[23 18] . average
[23 18] . [sum 1.0 *] [size] cleave /
[23 18] [sum 1.0 *] . [size] cleave /
[23 18] [sum 1.0 *] [size] . cleave /
[23 18] [sum 1.0 *] [size] . [i] app2 [popd] dip /
[23 18] [sum 1.0 *] [size] [i] . app2 [popd] dip /
[23 18] [[sum 1.0 *] [23 18]] [i] . infra first [[size] [23 18]] [i] infra first [popd] dip /
[23 18] [sum 1.0 *] . i [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
[23 18] . sum 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
41 . 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
41 1.0 . * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
41.0 . [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
41.0 [[23 18]] . swaack first [[size] [23 18]] [i] infra first [popd] dip /
[23 18] [41.0] . first [[size] [23 18]] [i] infra first [popd] dip /
[23 18] 41.0 . [[size] [23 18]] [i] infra first [popd] dip /
[23 18] 41.0 [[size] [23 18]] . [i] infra first [popd] dip /
[23 18] 41.0 [[size] [23 18]] [i] . infra first [popd] dip /
[23 18] [size] . i [41.0 [23 18]] swaack first [popd] dip /
[23 18] . size [41.0 [23 18]] swaack first [popd] dip /
[23 18] . 0 swap [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
[23 18] 0 . swap [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
0 [23 18] . [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
0 [23 18] [pop ++] . step [41.0 [23 18]] swaack first [popd] dip /
0 23 [pop ++] . i [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
0 23 . pop ++ [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
0 . ++ [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
1 . [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
1 [18] . [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
1 [18] [pop ++] . step [41.0 [23 18]] swaack first [popd] dip /
1 18 [pop ++] . i [41.0 [23 18]] swaack first [popd] dip /
1 18 . pop ++ [41.0 [23 18]] swaack first [popd] dip /
1 . ++ [41.0 [23 18]] swaack first [popd] dip /
2 . [41.0 [23 18]] swaack first [popd] dip /
2 [41.0 [23 18]] . swaack first [popd] dip /
[23 18] 41.0 [2] . first [popd] dip /
[23 18] 41.0 2 . [popd] dip /
[23 18] 41.0 2 [popd] . dip /
[23 18] 41.0 . popd 2 /
41.0 . 2 /
41.0 2 . /
20.5 .
Replacing ``size`` with a Python version
----------------------------------------
Both ``sum`` and ``size`` each convert a sequence to a single value.
::
sum == 0 swap [+] step
size == 0 swap [pop ++] step
An efficient ``sum`` function is already in the library. But for
``size`` we can use a “compiled” version hand-written in Python to speed
up evaluation and make the trace more readable.
.. code:: ipython2
from joy.library import SimpleFunctionWrapper
from joy.utils.stack import iter_stack
@SimpleFunctionWrapper
def size(stack):
'''Return the size of the sequence on the stack.'''
sequence, stack = stack
n = 0
for _ in iter_stack(sequence):
n += 1
return n, stack
Now we replace the old version in the dictionary with the new version,
and re-evaluate the expression.
.. code:: ipython2
D['size'] = size
A shorter trace
---------------
You can see that ``size`` now executes in a single step.
.. code:: ipython2
V('[23 18] average')
.. parsed-literal::
. [23 18] average
[23 18] . average
[23 18] . [sum 1.0 *] [size] cleave /
[23 18] [sum 1.0 *] . [size] cleave /
[23 18] [sum 1.0 *] [size] . cleave /
[23 18] [sum 1.0 *] [size] . [i] app2 [popd] dip /
[23 18] [sum 1.0 *] [size] [i] . app2 [popd] dip /
[23 18] [[sum 1.0 *] [23 18]] [i] . infra first [[size] [23 18]] [i] infra first [popd] dip /
[23 18] [sum 1.0 *] . i [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
[23 18] . sum 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
41 . 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
41 1.0 . * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
41.0 . [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
41.0 [[23 18]] . swaack first [[size] [23 18]] [i] infra first [popd] dip /
[23 18] [41.0] . first [[size] [23 18]] [i] infra first [popd] dip /
[23 18] 41.0 . [[size] [23 18]] [i] infra first [popd] dip /
[23 18] 41.0 [[size] [23 18]] . [i] infra first [popd] dip /
[23 18] 41.0 [[size] [23 18]] [i] . infra first [popd] dip /
[23 18] [size] . i [41.0 [23 18]] swaack first [popd] dip /
[23 18] . size [41.0 [23 18]] swaack first [popd] dip /
2 . [41.0 [23 18]] swaack first [popd] dip /
2 [41.0 [23 18]] . swaack first [popd] dip /
[23 18] 41.0 [2] . first [popd] dip /
[23 18] 41.0 2 . [popd] dip /
[23 18] 41.0 2 [popd] . dip /
[23 18] 41.0 . popd 2 /
41.0 . 2 /
41.0 2 . /
20.5 .

View File

@ -0,0 +1,336 @@
The Four Fundamental Operations of Definite Action
==================================================
All definite actions (computer program) can be defined by four
fundamental patterns of combination:
1. Sequence
2. Branch
3. Loop
4. Parallel
Sequence
--------
Do one thing after another. In joy this is represented by putting two
symbols together, juxtaposition:
::
foo bar
Operations have inputs and outputs. The outputs of ``foo`` must be
compatible in “arity”, type, and shape with the inputs of ``bar``.
Branch
------
Do one thing or another.
::
boolean [F] [T] branch
t [F] [T] branch
----------------------
T
f [F] [T] branch
----------------------
F
branch == unit cons swap pick i
boolean [F] [T] branch
boolean [F] [T] unit cons swap pick i
boolean [F] [[T]] cons swap pick i
boolean [[F] [T]] swap pick i
[[F] [T]] boolean pick i
[F-or-T] i
Given some branch function ``G``:
::
G == [F] [T] branch
Used in a sequence like so:
::
foo G bar
The inputs and outputs of ``F`` and ``T`` must be compatible with the
outputs for ``foo`` and the inputs of ``bar``, respectively.
::
foo F bar
foo T bar
``ifte``
~~~~~~~~
Often it will be easier on the programmer to write branching code with
the predicate specified in a quote. The ``ifte`` combinator provides
this (``T`` for “then” and ``E`` for “else”):
::
[P] [T] [E] ifte
Defined in terms of ``branch``:
::
ifte == [nullary not] dip branch
In this case, ``P`` must be compatible with the stack and return a
Boolean value, and ``T`` and ``E`` both must be compatible with the
preceeding and following functions, as described above for ``F`` and
``T``. (Note that in the current implementation we are depending on
Python for the underlying semantics, so the Boolean value doesnt *have*
to be Boolean because Pythons rules for “truthiness” will be used to
evaluate it. I reflect this in the structure of the stack effect comment
of ``branch``, it will only accept Boolean values, and in the definition
of ``ifte`` above by including ``not`` in the quote, which also has the
effect that the subject quotes are in the proper order for ``branch``.)
Loop
----
Do one thing zero or more times.
::
boolean [Q] loop
t [Q] loop
----------------
Q [Q] loop
... f [Q] loop
--------------------
...
The ``loop`` combinator generates a copy of itself in the true branch.
This is the hallmark of recursive defintions. In Thun there is no
equivalent to conventional loops. (There is, however, the ``x``
combinator, defined as ``x == dup i``, which permits recursive
constructs that do not need to be directly self-referential, unlike
``loop`` and ``genrec``.)
::
loop == [] swap [dup dip loop] cons branch
boolean [Q] loop
boolean [Q] [] swap [dup dip loop] cons branch
boolean [] [Q] [dup dip loop] cons branch
boolean [] [[Q] dup dip loop] branch
In action the false branch does nothing while the true branch does:
::
t [] [[Q] dup dip loop] branch
[Q] dup dip loop
[Q] [Q] dip loop
Q [Q] loop
Because ``loop`` expects and consumes a Boolean value, the ``Q``
function must be compatible with the previous stack *and itself* with a
boolean flag for the next iteration:
::
Q == G b
Q [Q] loop
G b [Q] loop
G Q [Q] loop
G G b [Q] loop
G G Q [Q] loop
G G G b [Q] loop
G G G
``while``
~~~~~~~~~
Keep doing ``B`` *while* some predicate ``P`` is true. This is
convenient as the predicate function is made nullary automatically and
the body function can be designed without regard to leaving a Boolean
flag for the next iteration:
::
[P] [B] while
--------------------------------------
[P] nullary [B [P] nullary] loop
while == swap [nullary] cons dup dipd concat loop
[P] [B] while
[P] [B] swap [nullary] cons dup dipd concat loop
[B] [P] [nullary] cons dup dipd concat loop
[B] [[P] nullary] dup dipd concat loop
[B] [[P] nullary] [[P] nullary] dipd concat loop
[P] nullary [B] [[P] nullary] concat loop
[P] nullary [B [P] nullary] loop
Parallel
--------
The *parallel* operation indicates that two (or more) functions *do not
interfere* with each other and so can run in parallel. The main
difficulty in this sort of thing is orchestrating the recombining
(“join” or “wait”) of the results of the functions after they finish.
The current implementaions and the following definitions *are not
actually parallel* (yet), but there is no reason they couldnt be
reimplemented in terms of e.g. Python threads. I am not concerned with
performance of the system just yet, only the elegance of the code it
allows us to write.
``cleave``
~~~~~~~~~~
Joy has a few parallel combinators, the main one being ``cleave``:
::
... x [A] [B] cleave
---------------------------------------------------------
... [x ...] [A] infra first [x ...] [B] infra first
---------------------------------------------------------
... a b
The ``cleave`` combinator expects a value and two quotes and it executes
each quote in “separate universes” such that neither can affect the
other, then it takes the first item from the stack in each universe and
replaces the value and quotes with their respective results.
(I think this corresponds to the “fork” operator, the little
upward-pointed triangle, that takes two functions ``A :: x -> a`` and
``B :: x -> b`` and returns a function ``F :: x -> (a, b)``, in Conal
Elliotts “Compiling to Categories” paper, et. al.)
Just a thought, if you ``cleave`` two jobs and one requires more time to
finish than the other youd like to be able to assign resources
accordingly so that they both finish at the same time.
“Apply” Functions
~~~~~~~~~~~~~~~~~
There are also ``app2`` and ``app3`` which run a single quote on more
than one value:
::
... y x [Q] app2
---------------------------------------------------------
... [y ...] [Q] infra first [x ...] [Q] infra first
... z y x [Q] app3
---------------------------------
... [z ...] [Q] infra first
[y ...] [Q] infra first
[x ...] [Q] infra first
Because the quoted program can be ``i`` we can define ``cleave`` in
terms of ``app2``:
::
cleave == [i] app2 [popd] dip
(Im not sure why ``cleave`` was specified to take that value, I may
make a combinator that does the same thing but without expecting a
value.)
::
clv == [i] app2
[A] [B] clv
------------------
a b
``map``
~~~~~~~
The common ``map`` function in Joy should also be though of as a
*parallel* operator:
::
[a b c ...] [Q] map
There is no reason why the implementation of ``map`` couldnt distribute
the ``Q`` function over e.g. a pool of worker CPUs.
``pam``
~~~~~~~
One of my favorite combinators, the ``pam`` combinator is just:
::
pam == [i] map
This can be used to run any number of programs separately on the current
stack and combine their (first) outputs in a result list.
::
[[A] [B] [C] ...] [i] map
-------------------------------
[ a b c ...]
Handling Other Kinds of Join
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``cleave`` operators and others all have pretty brutal join
semantics: everything works and we always wait for every
sub-computation. We can imagine a few different potentially useful
patterns of “joining” results from parallel combinators.
first-to-finish
^^^^^^^^^^^^^^^
Thinking about variations of ``pam`` there could be one that only
returns the first result of the first-to-finish sub-program, or the
stack could be replaced by its output stack.
The other sub-programs would be cancelled.
“Fulminators”
^^^^^^^^^^^^^
Also known as “Futures” or “Promises” (by *everybody* else. “Fulinators”
is what I was going to call them when I was thinking about implementing
them in Thun.)
The runtime could be amended to permit “thunks” representing the results
of in-progress computations to be left on the stack and picked up by
subsequent functions. These would themselves be able to leave behind
more “thunks”, the values of which depend on the eventual resolution of
the values of the previous thunks.
In this way you can create “chains” (and more complex shapes) out of
normal-looking code that consist of a kind of call-graph interspersed
with “asyncronous” … events?
In any case, until I can find a rigorous theory that shows that this
sort of thing works perfectly in Joy code Im not going to worry about
it. (And I think the Categories can deal with it anyhow? Incremental
evaluation, yeah?)

View File

@ -0,0 +1,620 @@
Treating Trees II: ``treestep``
===============================
Lets consider a tree structure, similar to one described `“Why
functional programming matters” by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__,
that consists of a node value followed by zero or more child trees. (The
asterisk is meant to indicate the `Kleene
star <https://en.wikipedia.org/wiki/Kleene_star>`__.)
::
tree = [] | [node tree*]
In the spirit of ``step`` we are going to define a combinator
``treestep`` which expects a tree and three additional items: a
base-case function ``[B]``, and two quoted programs ``[N]`` and ``[C]``.
::
tree [B] [N] [C] treestep
If the current tree node is empty then just execute ``B``:
::
[] [B] [N] [C] treestep
---------------------------
[] B
Otherwise, evaluate ``N`` on the node value, ``map`` the whole function
(abbreviated here as ``K``) over the child trees recursively, and then
combine the result with ``C``.
::
[node tree*] [B] [N] [C] treestep
--------------------------------------- w/ K == [B] [N] [C] treestep
node N [tree*] [K] map C
(Later on well experiment with making ``map`` part of ``C`` so you can
use other combinators.)
Derive the recursive function.
------------------------------
We can begin to derive it by finding the ``ifte`` stage that ``genrec``
will produce.
::
K == [not] [B] [R0] [R1] genrec
== [not] [B] [R0 [K] R1] ifte
So we just have to derive ``J``:
::
J == R0 [K] R1
The behavior of ``J`` is to accept a (non-empty) tree node and arrive at
the desired outcome.
::
[node tree*] J
------------------------------
node N [tree*] [K] map C
So ``J`` will have some form like:
::
J == ... [N] ... [K] ... [C] ...
Lets dive in. First, unquote the node and ``dip`` ``N``.
::
[node tree*] uncons [N] dip
node [tree*] [N] dip
node N [tree*]
Next, ``map`` ``K`` over the child trees and combine with ``C``.
::
node N [tree*] [K] map C
node N [tree*] [K] map C
node N [K.tree*] C
So:
::
J == uncons [N] dip [K] map C
Plug it in and convert to ``genrec``:
::
K == [not] [B] [J ] ifte
== [not] [B] [uncons [N] dip [K] map C] ifte
== [not] [B] [uncons [N] dip] [map C] genrec
Extract the givens to parameterize the program.
-----------------------------------------------
Working backwards:
::
[not] [B] [uncons [N] dip] [map C] genrec
[B] [not] swap [uncons [N] dip] [map C] genrec
[B] [uncons [N] dip] [[not] swap] dip [map C] genrec
^^^^^^^^^^^^^^^^
[B] [[N] dip] [uncons] swoncat [[not] swap] dip [map C] genrec
[B] [N] [dip] cons [uncons] swoncat [[not] swap] dip [map C] genrec
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Extract a couple of auxiliary definitions:
::
TS.0 == [[not] swap] dip
TS.1 == [dip] cons [uncons] swoncat
::
[B] [N] TS.1 TS.0 [map C] genrec
[B] [N] [map C] [TS.1 TS.0] dip genrec
[B] [N] [C] [map] swoncat [TS.1 TS.0] dip genrec
The givens are all to the left so we have our definition.
(alternate) Extract the givens to parameterize the program.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Working backwards:
::
[not] [B] [uncons [N] dip] [map C] genrec
[not] [B] [N] [dip] cons [uncons] swoncat [map C] genrec
[B] [N] [not] roll> [dip] cons [uncons] swoncat [map C] genrec
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Define ``treestep``
-------------------
.. code:: ipython2
from notebook_preamble import D, J, V, define, DefinitionWrapper
.. code:: ipython2
DefinitionWrapper.add_definitions('''
_treestep_0 == [[not] swap] dip
_treestep_1 == [dip] cons [uncons] swoncat
treegrind == [_treestep_1 _treestep_0] dip genrec
treestep == [map] swoncat treegrind
''', D)
Examples
--------
Consider trees, the nodes of which are integers. We can find the sum of
all nodes in a tree with this function:
::
sumtree == [pop 0] [] [sum +] treestep
.. code:: ipython2
define('sumtree == [pop 0] [] [sum +] treestep')
Running this function on an empty tree value gives zero:
::
[] [pop 0] [] [sum +] treestep
------------------------------------
0
.. code:: ipython2
J('[] sumtree') # Empty tree.
.. parsed-literal::
0
Running it on a non-empty node:
::
[n tree*] [pop 0] [] [sum +] treestep
n [tree*] [[pop 0] [] [sum +] treestep] map sum +
n [ ... ] sum +
n m +
n+m
.. code:: ipython2
J('[23] sumtree') # No child trees.
.. parsed-literal::
23
.. code:: ipython2
J('[23 []] sumtree') # Child tree, empty.
.. parsed-literal::
23
.. code:: ipython2
J('[23 [2 [4]] [3]] sumtree') # Non-empty child trees.
.. parsed-literal::
32
.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] sumtree') # Etc...
.. parsed-literal::
49
.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep') # Alternate "spelling".
.. parsed-literal::
49
.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep') # Replace each node.
.. parsed-literal::
[23 [23 [23] [23]] [23] [23 []]]
.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep')
.. parsed-literal::
[1 [1 [1] [1]] [1] [1 []]]
.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree')
.. parsed-literal::
6
.. code:: ipython2
J('[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep') # Combine replace and sum into one function.
.. parsed-literal::
6
.. code:: ipython2
J('[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep') # Combine replace and sum into one function.
.. parsed-literal::
3
Redefining the Ordered Binary Tree in terms of ``treestep``.
------------------------------------------------------------
::
Tree = [] | [[key value] left right]
What kind of functions can we write for this with our ``treestep``?
The pattern for processing a non-empty node is:
::
node N [tree*] [K] map C
Plugging in our BTree structure:
::
[key value] N [left right] [K] map C
Traversal
~~~~~~~~~
::
[key value] first [left right] [K] map i
key [value] [left right] [K] map i
key [left right] [K] map i
key [lkey rkey ] i
key lkey rkey
This doesnt quite work:
.. code:: ipython2
J('[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep')
.. parsed-literal::
3 'B' 'B'
Doesnt work because ``map`` extracts the ``first`` item of whatever its
mapped function produces. We have to return a list, rather than
depositing our results directly on the stack.
::
[key value] N [left right] [K] map C
[key value] first [left right] [K] map flatten cons
key [left right] [K] map flatten cons
key [[lk] [rk] ] flatten cons
key [ lk rk ] cons
[key lk rk ]
So:
::
[] [first] [flatten cons] treestep
.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep')
.. parsed-literal::
[3 2 9 5 4 8 6 7]
There we go.
In-order traversal
~~~~~~~~~~~~~~~~~~
From here:
::
key [[lk] [rk]] C
key [[lk] [rk]] i
key [lk] [rk] roll<
[lk] [rk] key swons concat
[lk] [key rk] concat
[lk key rk]
So:
::
[] [i roll< swons concat] [first] treestep
.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll< swons concat] treestep')
.. parsed-literal::
[2 3 4 5 6 7 8 9]
With ``treegrind``?
-------------------
The ``treegrind`` function doesnt include the ``map`` combinator, so
the ``[C]`` function must arrange to use some combinator on the quoted
recursive copy ``[K]``. With this function, the pattern for processing a
non-empty node is:
::
node N [tree*] [K] C
Plugging in our BTree structure:
::
[key value] N [left right] [K] C
.. code:: ipython2
J('[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind')
.. parsed-literal::
['key' 'value'] 'N' [['left'] ['right']] [[not] ['B'] [uncons ['N'] dip] ['C'] genrec] 'C'
``treegrind`` with ``step``
---------------------------
Iteration through the nodes
.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] ["N"] [step] treegrind')
.. parsed-literal::
[3 0] 'N' [2 0] 'N' [9 0] 'N' [5 0] 'N' [4 0] 'N' [8 0] 'N' [6 0] 'N' [7 0] 'N'
Sum the nodes keys.
.. code:: ipython2
J('0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind')
.. parsed-literal::
44
Rebuild the tree using ``map`` (imitating ``treestep``.)
.. code:: ipython2
J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind')
.. parsed-literal::
[[103 0] [[102 0] [] []] [[109 0] [[105 0] [[104 0] [] []] [[108 0] [[106 0] [] [[107 0] [] []]] []]] []]]
Do we have the flexibility to reimplement ``Tree-get``?
-------------------------------------------------------
I think we do:
::
[B] [N] [C] treegrind
Well start by saying that the base-case (the key is not in the tree) is
user defined, and the per-node function is just the query key literal:
::
[B] [query_key] [C] treegrind
This means we just have to define ``C`` from:
::
[key value] query_key [left right] [K] C
Lets try ``cmp``:
::
C == P [T>] [E] [T<] cmp
[key value] query_key [left right] [K] P [T>] [E] [T<] cmp
The predicate ``P``
~~~~~~~~~~~~~~~~~~~
Seems pretty easy (we must preserve the value in case the keys are
equal):
::
[key value] query_key [left right] [K] P
[key value] query_key [left right] [K] roll<
[key value] [left right] [K] query_key [roll< uncons swap] dip
[key value] [left right] [K] roll< uncons swap query_key
[left right] [K] [key value] uncons swap query_key
[left right] [K] key [value] swap query_key
[left right] [K] [value] key query_key
P == roll< [roll< uncons swap] dip
(Possibly with a swap at the end? Or just swap ``T<`` and ``T>``.)
So now:
::
[left right] [K] [value] key query_key [T>] [E] [T<] cmp
Becomes one of these three:
::
[left right] [K] [value] T>
[left right] [K] [value] E
[left right] [K] [value] T<
``E``
~~~~~
Easy.
::
E == roll> popop first
``T<`` and ``T>``
~~~~~~~~~~~~~~~~~
::
T< == pop [first] dip i
T> == pop [second] dip i
Putting it together
-------------------
::
T> == pop [first] dip i
T< == pop [second] dip i
E == roll> popop first
P == roll< [roll< uncons swap] dip
Tree-get == [P [T>] [E] [T<] cmp] treegrind
To me, that seems simpler than the ``genrec`` version.
.. code:: ipython2
DefinitionWrapper.add_definitions('''
T> == pop [first] dip i
T< == pop [second] dip i
E == roll> popop first
P == roll< [roll< uncons swap] dip
Tree-get == [P [T>] [E] [T<] cmp] treegrind
''', D)
.. code:: ipython2
J('''\
[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]
[] [5] Tree-get
''')
.. parsed-literal::
15
.. code:: ipython2
J('''\
[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]
[pop "nope"] [25] Tree-get
''')
.. parsed-literal::
'nope'

View File

@ -0,0 +1,171 @@
Type Checking
=============
.. code:: ipython2
import logging, sys
logging.basicConfig(
format='%(message)s',
stream=sys.stdout,
level=logging.INFO,
)
.. code:: ipython2
from joy.utils.types import (
doc_from_stack_effect,
infer,
reify,
unify,
FUNCTIONS,
JoyTypeError,
)
.. code:: ipython2
D = FUNCTIONS.copy()
del D['product']
globals().update(D)
An Example
----------
.. code:: ipython2
fi, fo = infer(pop, swap, rolldown, rrest, ccons)[0]
.. parsed-literal::
25 (--) ∘ pop swap rolldown rrest ccons
28 (a1 --) ∘ swap rolldown rrest ccons
31 (a3 a2 a1 -- a2 a3) ∘ rolldown rrest ccons
34 (a4 a3 a2 a1 -- a2 a3 a4) ∘ rrest ccons
37 ([a4 a5 ...1] a3 a2 a1 -- a2 a3 [...1]) ∘ ccons
40 ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) ∘
.. code:: ipython2
print doc_from_stack_effect(fi, fo)
.. parsed-literal::
([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1])
.. code:: ipython2
from joy.parser import text_to_expression
from joy.utils.stack import stack_to_string
.. code:: ipython2
e = text_to_expression('0 1 2 [3 4]') # reverse order
print stack_to_string(e)
.. parsed-literal::
[3 4] 2 1 0
.. code:: ipython2
u = unify(e, fi)[0]
u
.. parsed-literal::
{a1: 0, a2: 1, a3: 2, a4: 3, a5: 4, s2: (), s1: ()}
.. code:: ipython2
g = reify(u, (fi, fo))
print doc_from_stack_effect(*g)
.. parsed-literal::
(... [3 4 ] 2 1 0 -- ... [1 2 ])
Unification Works “in Reverse”
------------------------------
.. code:: ipython2
e = text_to_expression('[2 3]')
.. code:: ipython2
u = unify(e, fo)[0] # output side, not input side
u
.. parsed-literal::
{a2: 2, a3: 3, s2: (), s1: ()}
.. code:: ipython2
g = reify(u, (fi, fo))
print doc_from_stack_effect(*g)
.. parsed-literal::
(... [a4 a5 ] 3 2 a1 -- ... [2 3 ])
Failing a Check
---------------
.. code:: ipython2
fi, fo = infer(dup, mul)[0]
.. parsed-literal::
25 (--) ∘ dup mul
28 (a1 -- a1 a1) ∘ mul
31 (f1 -- f2) ∘
31 (i1 -- i2) ∘
.. code:: ipython2
e = text_to_expression('"two"')
print stack_to_string(e)
.. parsed-literal::
'two'
.. code:: ipython2
try:
unify(e, fi)
except JoyTypeError, err:
print err
.. parsed-literal::
Cannot unify 'two' and f1.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,352 @@
Traversing Datastructures with Zippers
======================================
This notebook is about using the “zipper” with joy datastructures. See
the `Zipper wikipedia
entry <https://en.wikipedia.org/wiki/Zipper_%28data_structure%29>`__ or
the original paper: `“FUNCTIONAL PEARL The Zipper” by Gérard
Huet <https://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf>`__
Given a datastructure on the stack we can navigate through it, modify
it, and rebuild it using the “zipper” technique.
.. code:: ipython2
from notebook_preamble import J, V, define
Trees
-----
In Joypy there arent any complex datastructures, just ints, floats,
strings, Symbols (strings that are names of functions) and sequences
(aka lists, aka quoted literals, aka aggregates, etc…), but we can build
`trees <https://en.wikipedia.org/wiki/Tree_%28data_structure%29>`__ out
of sequences.
.. code:: ipython2
J('[1 [2 [3 4 25 6] 7] 8]')
.. parsed-literal::
[1 [2 [3 4 25 6] 7] 8]
Zipper in Joy
-------------
Zippers work by keeping track of the current item, the already-seen
items, and the yet-to-be seen items as you traverse a datastructure (the
datastructure used to keep track of these items is the zipper.)
In Joy we can do this with the following words:
::
z-down == [] swap uncons swap
z-up == swons swap shunt
z-right == [swons] cons dip uncons swap
z-left == swons [uncons swap] dip swap
Lets use them to change 25 into 625. The first time a word is used I
show the trace so you can see how it works. If we were going to use
these a lot it would make sense to write Python versions for efficiency,
but see below.
.. code:: ipython2
define('z-down == [] swap uncons swap')
define('z-up == swons swap shunt')
define('z-right == [swons] cons dip uncons swap')
define('z-left == swons [uncons swap] dip swap')
.. code:: ipython2
V('[1 [2 [3 4 25 6] 7] 8] z-down')
.. parsed-literal::
. [1 [2 [3 4 25 6] 7] 8] z-down
[1 [2 [3 4 25 6] 7] 8] . z-down
[1 [2 [3 4 25 6] 7] 8] . [] swap uncons swap
[1 [2 [3 4 25 6] 7] 8] [] . swap uncons swap
[] [1 [2 [3 4 25 6] 7] 8] . uncons swap
[] 1 [[2 [3 4 25 6] 7] 8] . swap
[] [[2 [3 4 25 6] 7] 8] 1 .
.. code:: ipython2
V('[] [[2 [3 4 25 6] 7] 8] 1 z-right')
.. parsed-literal::
. [] [[2 [3 4 25 6] 7] 8] 1 z-right
[] . [[2 [3 4 25 6] 7] 8] 1 z-right
[] [[2 [3 4 25 6] 7] 8] . 1 z-right
[] [[2 [3 4 25 6] 7] 8] 1 . z-right
[] [[2 [3 4 25 6] 7] 8] 1 . [swons] cons dip uncons swap
[] [[2 [3 4 25 6] 7] 8] 1 [swons] . cons dip uncons swap
[] [[2 [3 4 25 6] 7] 8] [1 swons] . dip uncons swap
[] . 1 swons [[2 [3 4 25 6] 7] 8] uncons swap
[] 1 . swons [[2 [3 4 25 6] 7] 8] uncons swap
[] 1 . swap cons [[2 [3 4 25 6] 7] 8] uncons swap
1 [] . cons [[2 [3 4 25 6] 7] 8] uncons swap
[1] . [[2 [3 4 25 6] 7] 8] uncons swap
[1] [[2 [3 4 25 6] 7] 8] . uncons swap
[1] [2 [3 4 25 6] 7] [8] . swap
[1] [8] [2 [3 4 25 6] 7] .
.. code:: ipython2
J('[1] [8] [2 [3 4 25 6] 7] z-down')
.. parsed-literal::
[1] [8] [] [[3 4 25 6] 7] 2
.. code:: ipython2
J('[1] [8] [] [[3 4 25 6] 7] 2 z-right')
.. parsed-literal::
[1] [8] [2] [7] [3 4 25 6]
.. code:: ipython2
J('[1] [8] [2] [7] [3 4 25 6] z-down')
.. parsed-literal::
[1] [8] [2] [7] [] [4 25 6] 3
.. code:: ipython2
J('[1] [8] [2] [7] [] [4 25 6] 3 z-right')
.. parsed-literal::
[1] [8] [2] [7] [3] [25 6] 4
.. code:: ipython2
J('[1] [8] [2] [7] [3] [25 6] 4 z-right')
.. parsed-literal::
[1] [8] [2] [7] [4 3] [6] 25
.. code:: ipython2
J('[1] [8] [2] [7] [4 3] [6] 25 sqr')
.. parsed-literal::
[1] [8] [2] [7] [4 3] [6] 625
.. code:: ipython2
V('[1] [8] [2] [7] [4 3] [6] 625 z-up')
.. parsed-literal::
. [1] [8] [2] [7] [4 3] [6] 625 z-up
[1] . [8] [2] [7] [4 3] [6] 625 z-up
[1] [8] . [2] [7] [4 3] [6] 625 z-up
[1] [8] [2] . [7] [4 3] [6] 625 z-up
[1] [8] [2] [7] . [4 3] [6] 625 z-up
[1] [8] [2] [7] [4 3] . [6] 625 z-up
[1] [8] [2] [7] [4 3] [6] . 625 z-up
[1] [8] [2] [7] [4 3] [6] 625 . z-up
[1] [8] [2] [7] [4 3] [6] 625 . swons swap shunt
[1] [8] [2] [7] [4 3] [6] 625 . swap cons swap shunt
[1] [8] [2] [7] [4 3] 625 [6] . cons swap shunt
[1] [8] [2] [7] [4 3] [625 6] . swap shunt
[1] [8] [2] [7] [625 6] [4 3] . shunt
[1] [8] [2] [7] [3 4 625 6] .
.. code:: ipython2
J('[1] [8] [2] [7] [3 4 625 6] z-up')
.. parsed-literal::
[1] [8] [2 [3 4 625 6] 7]
.. code:: ipython2
J('[1] [8] [2 [3 4 625 6] 7] z-up')
.. parsed-literal::
[1 [2 [3 4 625 6] 7] 8]
``dip`` and ``infra``
---------------------
In Joy we have the ``dip`` and ``infra`` combinators which can “target”
or “address” any particular item in a Joy tree structure.
.. code:: ipython2
V('[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra')
.. parsed-literal::
. [1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra
[1 [2 [3 4 25 6] 7] 8] . [[[[[[sqr] dipd] infra] dip] infra] dip] infra
[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] . infra
8 [2 [3 4 25 6] 7] 1 . [[[[[sqr] dipd] infra] dip] infra] dip [] swaack
8 [2 [3 4 25 6] 7] 1 [[[[[sqr] dipd] infra] dip] infra] . dip [] swaack
8 [2 [3 4 25 6] 7] . [[[[sqr] dipd] infra] dip] infra 1 [] swaack
8 [2 [3 4 25 6] 7] [[[[sqr] dipd] infra] dip] . infra 1 [] swaack
7 [3 4 25 6] 2 . [[[sqr] dipd] infra] dip [8] swaack 1 [] swaack
7 [3 4 25 6] 2 [[[sqr] dipd] infra] . dip [8] swaack 1 [] swaack
7 [3 4 25 6] . [[sqr] dipd] infra 2 [8] swaack 1 [] swaack
7 [3 4 25 6] [[sqr] dipd] . infra 2 [8] swaack 1 [] swaack
6 25 4 3 . [sqr] dipd [7] swaack 2 [8] swaack 1 [] swaack
6 25 4 3 [sqr] . dipd [7] swaack 2 [8] swaack 1 [] swaack
6 25 . sqr 4 3 [7] swaack 2 [8] swaack 1 [] swaack
6 25 . dup mul 4 3 [7] swaack 2 [8] swaack 1 [] swaack
6 25 25 . mul 4 3 [7] swaack 2 [8] swaack 1 [] swaack
6 625 . 4 3 [7] swaack 2 [8] swaack 1 [] swaack
6 625 4 . 3 [7] swaack 2 [8] swaack 1 [] swaack
6 625 4 3 . [7] swaack 2 [8] swaack 1 [] swaack
6 625 4 3 [7] . swaack 2 [8] swaack 1 [] swaack
7 [3 4 625 6] . 2 [8] swaack 1 [] swaack
7 [3 4 625 6] 2 . [8] swaack 1 [] swaack
7 [3 4 625 6] 2 [8] . swaack 1 [] swaack
8 [2 [3 4 625 6] 7] . 1 [] swaack
8 [2 [3 4 625 6] 7] 1 . [] swaack
8 [2 [3 4 625 6] 7] 1 [] . swaack
[1 [2 [3 4 625 6] 7] 8] .
If you read the trace carefully youll see that about half of it is the
``dip`` and ``infra`` combinators de-quoting programs and “digging” into
the subject datastructure. Instead of maintaining temporary results on
the stack they are pushed into the pending expression (continuation).
When ``sqr`` has run the rest of the pending expression rebuilds the
datastructure.
``Z``
-----
Imagine a function ``Z`` that accepts a sequence of ``dip`` and
``infra`` combinators, a quoted program ``[Q]``, and a datastructure to
work on. It would effectively execute the quoted program as if it had
been embedded in a nested series of quoted programs, e.g.:
::
[...] [Q] [dip dip infra dip infra dip infra] Z
-------------------------------------------------------------
[...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
The ``Z`` function isnt hard to make.
.. code:: ipython2
define('Z == [[] cons cons] step i')
Here it is in action in a simplified scenario.
.. code:: ipython2
V('1 [2 3 4] Z')
.. parsed-literal::
. 1 [2 3 4] Z
1 . [2 3 4] Z
1 [2 3 4] . Z
1 [2 3 4] . [[] cons cons] step i
1 [2 3 4] [[] cons cons] . step i
1 2 [[] cons cons] . i [3 4] [[] cons cons] step i
1 2 . [] cons cons [3 4] [[] cons cons] step i
1 2 [] . cons cons [3 4] [[] cons cons] step i
1 [2] . cons [3 4] [[] cons cons] step i
[1 2] . [3 4] [[] cons cons] step i
[1 2] [3 4] . [[] cons cons] step i
[1 2] [3 4] [[] cons cons] . step i
[1 2] 3 [[] cons cons] . i [4] [[] cons cons] step i
[1 2] 3 . [] cons cons [4] [[] cons cons] step i
[1 2] 3 [] . cons cons [4] [[] cons cons] step i
[1 2] [3] . cons [4] [[] cons cons] step i
[[1 2] 3] . [4] [[] cons cons] step i
[[1 2] 3] [4] . [[] cons cons] step i
[[1 2] 3] [4] [[] cons cons] . step i
[[1 2] 3] 4 [[] cons cons] . i i
[[1 2] 3] 4 . [] cons cons i
[[1 2] 3] 4 [] . cons cons i
[[1 2] 3] [4] . cons i
[[[1 2] 3] 4] . i
. [[1 2] 3] 4
[[1 2] 3] . 4
[[1 2] 3] 4 .
And here it is doing the main thing.
.. code:: ipython2
J('[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z')
.. parsed-literal::
[1 [2 [3 4 625 6] 7] 8]
Addressing
----------
Because we are only using two combinators we could replace the list with
a string made from only two characters.
::
[...] [Q] 'ddididi' Zstr
-------------------------------------------------------------
[...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
The string can be considered a name or address for an item in the
subject datastructure.
Determining the right “path” for an item in a tree.
---------------------------------------------------
Its easy to read off (in reverse) the right sequence of “d” and “i”
from the subject datastructure:
::
[ n [ n [ n n x ...
i d i d i d d Bingo!

View File

@ -0,0 +1,26 @@
Essays about Programming in Joy
===============================
These essays are adapted from Jupyter notebooks. I hope to have those hosted somewhere where people can view them "live" and interact with them, possibly on MS Azure. For now, Sphinx does such a great job rendering the HTML that I am copying over some notebooks in ReST format and hand-editing them into these documents.
.. toctree::
:glob:
:maxdepth: 2
Developing
Quadratic
Replacing
Recursion_Combinators
Ordered_Binary_Trees
Treestep
Generator_Programs
Newton-Raphson
Zipper
Types
TypeChecking
NoUpdates
Categorical
The_Four_Operations
Derivatives_of_Regular_Expressions

View File

@ -0,0 +1,153 @@
Type Inference of Joy Expressions
=================================
UPDATE: May 2020 - I removed the type inference code in `joy.utils.types`
but you can find it in the `v0.4.0` tag here:
https://osdn.net/projects/joypy/scm/hg/Joypy/tags
Two kinds of type inference are provided, a simple inferencer that can
handle functions that have a single stack effect (aka "type signature")
and that can generate Python code for a limited subset of those
functions, and a more complex inferencer/interpreter hybrid that can
infer the stack effects of most Joy expressions, including multiple stack
effects, unbounded sequences of values, and combinators (if enough
information is available.)
``joy.utils.types``
-------------------
Curently (asterix after name indicates a function that can be
auto-compiled to Python)::
_Tree_add_Ee = ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) *
_Tree_delete_R0 = ([a2 ...1] a1 -- [a2 ...1] a2 a1 a1) *
_Tree_delete_clear_stuff = (a3 a2 [a1 ...1] -- [...1]) *
_Tree_get_E = ([a3 a4 ...1] a2 a1 -- a4) *
add = (n1 n2 -- n3)
and = (b1 b2 -- b3)
bool = (a1 -- b1)
ccons = (a2 a1 [...1] -- [a2 a1 ...1]) *
cons = (a1 [...0] -- [a1 ...0]) *
div = (n1 n2 -- n3)
divmod = (n2 n1 -- n4 n3)
dup = (a1 -- a1 a1) *
dupd = (a2 a1 -- a2 a2 a1) *
dupdd = (a3 a2 a1 -- a3 a3 a2 a1) *
eq = (n1 n2 -- b1)
first = ([a1 ...1] -- a1) *
first_two = ([a1 a2 ...1] -- a1 a2) *
floordiv = (n1 n2 -- n3)
fourth = ([a1 a2 a3 a4 ...1] -- a4) *
ge = (n1 n2 -- b1)
gt = (n1 n2 -- b1)
le = (n1 n2 -- b1)
lshift = (n1 n2 -- n3)
lt = (n1 n2 -- b1)
modulus = (n1 n2 -- n3)
mul = (n1 n2 -- n3)
ne = (n1 n2 -- b1)
neg = (n1 -- n2)
not = (a1 -- b1)
over = (a2 a1 -- a2 a1 a2) *
pm = (n2 n1 -- n4 n3)
pop = (a1 --) *
popd = (a2 a1 -- a1) *
popdd = (a3 a2 a1 -- a2 a1) *
popop = (a2 a1 --) *
popopd = (a3 a2 a1 -- a1) *
popopdd = (a4 a3 a2 a1 -- a2 a1) *
pow = (n1 n2 -- n3)
pred = (n1 -- n2)
rest = ([a1 ...0] -- [...0]) *
rolldown = (a1 a2 a3 -- a2 a3 a1) *
rollup = (a1 a2 a3 -- a3 a1 a2) *
rrest = ([a1 a2 ...1] -- [...1]) *
rshift = (n1 n2 -- n3)
second = ([a1 a2 ...1] -- a2) *
sqrt = (n1 -- n2)
stack = (... -- ... [...]) *
stuncons = (... a1 -- ... a1 a1 [...]) *
stununcons = (... a2 a1 -- ... a2 a1 a1 a2 [...]) *
sub = (n1 n2 -- n3)
succ = (n1 -- n2)
swaack = ([...1] -- [...0]) *
swap = (a1 a2 -- a2 a1) *
swons = ([...1] a1 -- [a1 ...1]) *
third = ([a1 a2 a3 ...1] -- a3) *
truediv = (n1 n2 -- n3)
tuck = (a2 a1 -- a1 a2 a1) *
uncons = ([a1 ...0] -- a1 [...0]) *
unit = (a1 -- [a1 ]) *
unswons = ([a1 ...1] -- [...1] a1) *
Example output of the ``infer()`` function. The first number on each
line is the depth of the Python stack. It goes down when the function
backtracks. The next thing on each line is the currently-computed stack
effect so far. It starts with the empty "identity function" and proceeds
through the expression, which is the rest of each line. The function
acts like an interpreter but instead of executing the terms of the
expression it composes them, but for combinators it *does* execute them,
using the output side of the stack effect as the stack. This seems to
work fine. With proper definitions for the behavior of the combinators
that can have more than one effect (like ``branch`` or ``loop``) the
``infer()`` function seems to be able to handle anything I throw at it so
far.
::
7 (--) ∘ pop swap rolldown rest rest cons cons
10 (a1 --) ∘ swap rolldown rest rest cons cons
13 (a3 a2 a1 -- a2 a3) ∘ rolldown rest rest cons cons
16 (a4 a3 a2 a1 -- a2 a3 a4) ∘ rest rest cons cons
19 ([a4 ...1] a3 a2 a1 -- a2 a3 [...1]) ∘ rest cons cons
22 ([a4 a5 ...1] a3 a2 a1 -- a2 a3 [...1]) ∘ cons cons
25 ([a4 a5 ...1] a3 a2 a1 -- a2 [a3 ...1]) ∘ cons
28 ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) ∘
----------------------------------------
([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1])
Here's another example (implementing ``ifte``) using some combinators::
7 (--) ∘ [pred] [mul] [div] [nullary bool] dipd branch
8 (-- [pred ...2]) ∘ [mul] [div] [nullary bool] dipd branch
9 (-- [pred ...2] [mul ...3]) ∘ [div] [nullary bool] dipd branch
10 (-- [pred ...2] [mul ...3] [div ...4]) ∘ [nullary bool] dipd branch
11 (-- [pred ...2] [mul ...3] [div ...4] [nullary bool ...5]) ∘ dipd branch
15 (-- [pred ...5]) ∘ nullary bool [mul] [div] branch
19 (-- [pred ...2]) ∘ [stack] dinfrirst bool [mul] [div] branch
20 (-- [pred ...2] [stack ]) ∘ dinfrirst bool [mul] [div] branch
22 (-- [pred ...2] [stack ]) ∘ dip infra first bool [mul] [div] branch
26 (--) ∘ stack [pred] infra first bool [mul] [div] branch
29 (... -- ... [...]) ∘ [pred] infra first bool [mul] [div] branch
30 (... -- ... [...] [pred ...1]) ∘ infra first bool [mul] [div] branch
34 (--) ∘ pred s1 swaack first bool [mul] [div] branch
37 (n1 -- n2) ∘ [n1] swaack first bool [mul] [div] branch
38 (... n1 -- ... n2 [n1 ...]) ∘ swaack first bool [mul] [div] branch
41 (... n1 -- ... n1 [n2 ...]) ∘ first bool [mul] [div] branch
44 (n1 -- n1 n2) ∘ bool [mul] [div] branch
47 (n1 -- n1 b1) ∘ [mul] [div] branch
48 (n1 -- n1 b1 [mul ...1]) ∘ [div] branch
49 (n1 -- n1 b1 [mul ...1] [div ...2]) ∘ branch
53 (n1 -- n1) ∘ div
56 (f2 f1 -- f3) ∘
56 (i1 f1 -- f2) ∘
56 (f1 i1 -- f2) ∘
56 (i2 i1 -- f1) ∘
53 (n1 -- n1) ∘ mul
56 (f2 f1 -- f3) ∘
56 (i1 f1 -- f2) ∘
56 (f1 i1 -- f2) ∘
56 (i2 i1 -- i3) ∘
----------------------------------------
(f2 f1 -- f3)
(i1 f1 -- f2)
(f1 i1 -- f2)
(i2 i1 -- f1)
(i2 i1 -- i3)

View File

@ -1,61 +1,9 @@
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
body {
font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
font-family: Georgia, serif;
font-size: 17px;
background-color: #fff;
color: #000;
@ -159,7 +107,7 @@ div.sphinxsidebarwrapper p.blurb {
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: 'Garamond', 'Georgia', serif;
font-family: Georgia, serif;
color: #444;
font-size: 24px;
font-weight: normal;
@ -203,7 +151,7 @@ div.sphinxsidebar ul li.toctree-l2 > a {
div.sphinxsidebar input {
border: 1px solid #CCC;
font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
font-family: Georgia, serif;
font-size: 1em;
}
@ -218,6 +166,19 @@ div.sphinxsidebar hr {
width: 50%;
}
div.sphinxsidebar .badge {
border-bottom: none;
}
div.sphinxsidebar .badge:hover {
border-bottom: none;
}
/* To address an issue with donation coming after search */
div.sphinxsidebar h3.donation {
margin-top: 10px;
}
/* -- body styles ----------------------------------------------------------- */
a {
@ -236,7 +197,7 @@ div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: 'Garamond', 'Georgia', serif;
font-family: Georgia, serif;
font-weight: normal;
margin: 30px 0px 10px 0px;
padding: 0;
@ -277,7 +238,7 @@ div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
}
div.admonition p.admonition-title {
font-family: 'Garamond', 'Georgia', serif;
font-family: Georgia, serif;
font-weight: normal;
font-size: 24px;
margin: 0 0 10px 0;
@ -366,7 +327,7 @@ p.admonition-title:after {
}
pre, tt, code {
font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-size: 0.9em;
}
@ -690,4 +651,51 @@ table.docutils.citation, table.docutils.citation td, table.docutils.citation th
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
/* relbar */
.related {
line-height: 30px;
width: 100%;
font-size: 0.9rem;
}
.related.top {
border-bottom: 1px solid #EEE;
margin-bottom: 20px;
}
.related.bottom {
border-top: 1px solid #EEE;
}
.related ul {
padding: 0;
margin: 0;
list-style: none;
}
.related li {
display: inline;
}
nav#rellinks {
float: right;
}
nav#rellinks li+li:before {
content: "|";
}
nav#breadcrumbs li+li:before {
content: "\00BB";
}
/* Hide certain items when printing */
@media print {
div.related {
display: none;
}
}

View File

@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@ -15,6 +15,12 @@ div.clearer {
clear: both;
}
div.section::after {
display: block;
content: '';
clear: left;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
@ -81,6 +87,10 @@ div.sphinxsidebar input {
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
@ -120,7 +130,7 @@ ul.search li a {
font-weight: bold;
}
ul.search li div.context {
ul.search li p.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
@ -227,6 +237,16 @@ a.headerlink {
visibility: hidden;
}
a.brackets:before,
span.brackets > a:before{
content: "[";
}
a.brackets:after,
span.brackets > a:after {
content: "]";
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
@ -257,19 +277,25 @@ p.rubric {
font-weight: bold;
}
img.align-left, .figure.align-left, object.align-left {
img.align-left, figure.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, .figure.align-right, object.align-right {
img.align-right, figure.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, .figure.align-center, object.align-center {
img.align-center, figure.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
img.align-default, figure.align-default, .figure.align-default {
display: block;
margin-left: auto;
margin-right: auto;
@ -283,30 +309,41 @@ img.align-center, .figure.align-center, object.align-center {
text-align: center;
}
.align-default {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar {
div.sidebar,
aside.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px 7px 0 7px;
padding: 7px;
background-color: #ffe;
width: 40%;
float: right;
clear: right;
overflow-x: auto;
}
p.sidebar-title {
font-weight: bold;
}
div.admonition, div.topic, blockquote {
clear: left;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px 7px 0 7px;
padding: 7px;
margin: 10px 0 10px 0;
}
@ -328,10 +365,6 @@ div.admonition dt {
font-weight: bold;
}
div.admonition dl {
margin-bottom: 0;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
@ -342,9 +375,30 @@ div.body p.centered {
margin-top: 25px;
}
/* -- content of sidebars/topics/admonitions -------------------------------- */
div.sidebar > :last-child,
aside.sidebar > :last-child,
div.topic > :last-child,
div.admonition > :last-child {
margin-bottom: 0;
}
div.sidebar::after,
aside.sidebar::after,
div.topic::after,
div.admonition::after,
blockquote::after {
display: block;
content: '';
clear: both;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
margin-top: 10px;
margin-bottom: 10px;
border: 0;
border-collapse: collapse;
}
@ -354,6 +408,11 @@ table.align-center {
margin-right: auto;
}
table.align-default {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
@ -387,22 +446,34 @@ table.citation td {
border-bottom: none;
}
th > :first-child,
td > :first-child {
margin-top: 0px;
}
th > :last-child,
td > :last-child {
margin-bottom: 0px;
}
/* -- figures --------------------------------------------------------------- */
div.figure {
div.figure, figure {
margin: 0.5em;
padding: 0.5em;
}
div.figure p.caption {
div.figure p.caption, figcaption {
padding: 0.3em;
}
div.figure p.caption span.caption-number {
div.figure p.caption span.caption-number,
figcaption span.caption-number {
font-style: italic;
}
div.figure p.caption span.caption-text {
div.figure p.caption span.caption-text,
figcaption span.caption-text {
}
/* -- field list styles ----------------------------------------------------- */
@ -427,6 +498,74 @@ table.field-list td, table.field-list th {
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist {
margin: 1em 0;
}
table.hlist td {
vertical-align: top;
}
/* -- object description styles --------------------------------------------- */
.sig {
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
}
.sig-name, code.descname {
background-color: transparent;
font-weight: bold;
}
.sig-name {
font-size: 1.1em;
}
code.descname {
font-size: 1.2em;
}
.sig-prename, code.descclassname {
background-color: transparent;
}
.optional {
font-size: 1.3em;
}
.sig-paren {
font-size: larger;
}
.sig-param.n {
font-style: italic;
}
/* C++ specific styling */
.sig-inline.c-texpr,
.sig-inline.cpp-texpr {
font-family: unset;
}
.sig.c .k, .sig.c .kt,
.sig.cpp .k, .sig.cpp .kt {
color: #0033B3;
}
.sig.c .m,
.sig.cpp .m {
color: #1750EB;
}
.sig.c .s, .sig.c .sc,
.sig.cpp .s, .sig.cpp .sc {
color: #067D17;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
@ -449,11 +588,78 @@ ol.upperroman {
list-style: upper-roman;
}
:not(li) > ol > li:first-child > :first-child,
:not(li) > ul > li:first-child > :first-child {
margin-top: 0px;
}
:not(li) > ol > li:last-child > :last-child,
:not(li) > ul > li:last-child > :last-child {
margin-bottom: 0px;
}
ol.simple ol p,
ol.simple ul p,
ul.simple ol p,
ul.simple ul p {
margin-top: 0;
}
ol.simple > li:not(:first-child) > p,
ul.simple > li:not(:first-child) > p {
margin-top: 0;
}
ol.simple p,
ul.simple p {
margin-bottom: 0;
}
dl.footnote > dt,
dl.citation > dt {
float: left;
margin-right: 0.5em;
}
dl.footnote > dd,
dl.citation > dd {
margin-bottom: 0em;
}
dl.footnote > dd:after,
dl.citation > dd:after {
content: "";
clear: both;
}
dl.field-list {
display: grid;
grid-template-columns: fit-content(30%) auto;
}
dl.field-list > dt {
font-weight: bold;
word-break: break-word;
padding-left: 0.5em;
padding-right: 5px;
}
dl.field-list > dt:after {
content: ":";
}
dl.field-list > dd {
padding-left: 0.5em;
margin-top: 0em;
margin-left: 0em;
margin-bottom: 0em;
}
dl {
margin-bottom: 15px;
}
dd p {
dd > :first-child {
margin-top: 0px;
}
@ -467,6 +673,11 @@ dd {
margin-left: 30px;
}
dl > dd:last-child,
dl > dd:last-child > :last-child {
margin-bottom: 0;
}
dt:target, span.highlighted {
background-color: #fbe54e;
}
@ -480,14 +691,6 @@ dl.glossary dt {
font-size: 1.1em;
}
.optional {
font-size: 1.3em;
}
.sig-paren {
font-size: larger;
}
.versionmodified {
font-style: italic;
}
@ -526,6 +729,13 @@ dl.glossary dt {
font-style: oblique;
}
.classifier:before {
font-style: normal;
margin: 0 0.5em;
content: ":";
display: inline-block;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
@ -538,6 +748,10 @@ pre {
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
pre, div[class*="highlight-"] {
clear: both;
}
span.pre {
-moz-hyphens: none;
-ms-hyphens: none;
@ -545,22 +759,57 @@ span.pre {
hyphens: none;
}
div[class*="highlight-"] {
margin: 1em 0;
}
td.linenos pre {
padding: 5px 0px;
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
margin-left: 0.5em;
display: block;
}
table.highlighttable tbody {
display: block;
}
table.highlighttable tr {
display: flex;
}
table.highlighttable td {
padding: 0 0.5em 0 0.5em;
margin: 0;
padding: 0;
}
table.highlighttable td.linenos {
padding-right: 0.5em;
}
table.highlighttable td.code {
flex: 1;
overflow: hidden;
}
.highlight .hll {
display: block;
}
div.highlight pre,
table.highlighttable pre {
margin: 0;
}
div.code-block-caption + div {
margin-top: 0;
}
div.code-block-caption {
margin-top: 1em;
padding: 2px 5px;
font-size: small;
}
@ -569,8 +818,14 @@ div.code-block-caption code {
background-color: transparent;
}
div.code-block-caption + div > div.highlight > pre {
margin-top: 0;
table.highlighttable td.linenos,
span.linenos,
div.highlight span.gp { /* gp: Generic.Prompt */
user-select: none;
-webkit-user-select: text; /* Safari fallback only */
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
}
div.code-block-caption span.caption-number {
@ -582,21 +837,7 @@ div.code-block-caption span.caption-text {
}
div.literal-block-wrapper {
padding: 1em 1em 0;
}
div.literal-block-wrapper div.highlight {
margin: 0;
}
code.descname {
background-color: transparent;
font-weight: bold;
font-size: 1.2em;
}
code.descclassname {
background-color: transparent;
margin: 1em 0;
}
code.xref, a code {
@ -637,8 +878,7 @@ span.eqno {
}
span.eqno a.headerlink {
position: relative;
left: 0px;
position: absolute;
z-index: 1;
}

View File

@ -4,7 +4,7 @@
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@ -29,9 +29,14 @@ if (!window.console || !console.firebug) {
/**
* small helper function to urldecode strings
*
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
*/
jQuery.urldecode = function(x) {
return decodeURIComponent(x).replace(/\+/g, ' ');
if (!x) {
return x
}
return decodeURIComponent(x.replace(/\+/g, ' '));
};
/**
@ -87,14 +92,13 @@ jQuery.fn.highlightText = function(text, className) {
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var bbox = span.getBBox();
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.x.baseVal.value = bbox.x;
var bbox = node.parentElement.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
var parentOfText = node.parentNode.parentNode;
addItems.push({
"parent": node.parentNode,
"target": rect});
@ -150,7 +154,9 @@ var Documentation = {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
this.initOnKeyListeners();
}
},
/**
@ -282,10 +288,12 @@ var Documentation = {
},
initOnKeyListeners: function() {
$(document).keyup(function(event) {
$(document).keydown(function(event) {
var activeElementType = document.activeElement.tagName;
// don't navigate when in search box or textarea
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {
// don't navigate when in search box, textarea, dropdown or button
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
&& activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey
&& !event.shiftKey) {
switch (event.keyCode) {
case 37: // left
var prevHref = $('link[rel="prev"]').prop('href');
@ -293,12 +301,14 @@ var Documentation = {
window.location.href = prevHref;
return false;
}
break;
case 39: // right
var nextHref = $('link[rel="next"]').prop('href');
if (nextHref) {
window.location.href = nextHref;
return false;
}
break;
}
}
});
@ -310,4 +320,4 @@ _ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});
});

View File

@ -1,9 +1,12 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '',
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.4.1',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
BUILDER: 'html',
FILE_SUFFIX: '.html',
LINK_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false
};

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,297 @@
/*
* language_data.js
* ~~~~~~~~~~~~~~~~
*
* This script contains the language-specific data used by searchtools.js,
* namely the list of stopwords, stemmer, scorer and splitter.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
/* Non-minified version is copied as a separate JS file, is available */
/**
* Porter Stemmer
*/
var Stemmer = function() {
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
};
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
}
}
var splitChars = (function() {
var result = {};
var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
var i, j, start, end;
for (i = 0; i < singles.length; i++) {
result[singles[i]] = true;
}
var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
[722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
[1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
[1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
[1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
[2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
[2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
[2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
[2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
[2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
[2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
[2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
[3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
[3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
[3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
[3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
[3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
[3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
[4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
[4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
[4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
[4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
[5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
[6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
[6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
[6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
[6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
[7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
[7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
[8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
[8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
[8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
[10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
[11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
[12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
[12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
[12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
[19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
[42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
[42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
[43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
[43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
[43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
[43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
[44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
[57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
[64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
[65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
[65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
for (i = 0; i < ranges.length; i++) {
start = ranges[i][0];
end = ranges[i][1];
for (j = start; j <= end; j++) {
result[j] = true;
}
}
return result;
})();
function splitQuery(query) {
var result = [];
var start = -1;
for (var i = 0; i < query.length; i++) {
if (splitChars[query.charCodeAt(i)]) {
if (start !== -1) {
result.push(query.slice(start, i));
start = -1;
}
} else if (start === -1) {
start = i;
}
}
if (start !== -1) {
result.push(query.slice(start));
}
return result;
}

View File

@ -1,5 +1,10 @@
pre { line-height: 125%; margin: 0; }
td.linenos pre { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }
span.linenos { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #eeffcc; }
.highlight { background: #eeffcc; }
.highlight .c { color: #408090; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #007020; font-weight: bold } /* Keyword */

View File

@ -1,331 +1,54 @@
/*
* searchtools.js_t
* searchtools.js
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilities for the full-text search.
*
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
if (!Scorer) {
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
/* Non-minified version JS is _stemmer.js if file is provided */
/**
* Porter Stemmer
*/
var Stemmer = function() {
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
var step2list = {
ational: 'ate',
tional: 'tion',
enci: 'ence',
anci: 'ance',
izer: 'ize',
bli: 'ble',
alli: 'al',
entli: 'ent',
eli: 'e',
ousli: 'ous',
ization: 'ize',
ation: 'ate',
ator: 'ate',
alism: 'al',
iveness: 'ive',
fulness: 'ful',
ousness: 'ous',
aliti: 'al',
iviti: 'ive',
biliti: 'ble',
logi: 'log'
// query found in title
title: 15,
partialTitle: 7,
// query found in terms
term: 5,
partialTerm: 2
};
}
var step3list = {
icate: 'ic',
ative: '',
alize: 'al',
iciti: 'ic',
ical: 'ic',
ful: '',
ness: ''
};
var c = "[^aeiou]"; // consonant
var v = "[aeiouy]"; // vowel
var C = c + "[^aeiouy]*"; // consonant sequence
var V = v + "[aeiou]*"; // vowel sequence
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
var s_v = "^(" + C + ")?" + v; // vowel in stem
this.stemWord = function (w) {
var stem;
var suffix;
var firstch;
var origword = w;
if (w.length < 3)
return w;
var re;
var re2;
var re3;
var re4;
firstch = w.substr(0,1);
if (firstch == "y")
w = firstch.toUpperCase() + w.substr(1);
// Step 1a
re = /^(.+?)(ss|i)es$/;
re2 = /^(.+?)([^s])s$/;
if (re.test(w))
w = w.replace(re,"$1$2");
else if (re2.test(w))
w = w.replace(re2,"$1$2");
// Step 1b
re = /^(.+?)eed$/;
re2 = /^(.+?)(ed|ing)$/;
if (re.test(w)) {
var fp = re.exec(w);
re = new RegExp(mgr0);
if (re.test(fp[1])) {
re = /.$/;
w = w.replace(re,"");
}
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1];
re2 = new RegExp(s_v);
if (re2.test(stem)) {
w = stem;
re2 = /(at|bl|iz)$/;
re3 = new RegExp("([^aeiouylsz])\\1$");
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re2.test(w))
w = w + "e";
else if (re3.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
else if (re4.test(w))
w = w + "e";
}
}
// Step 1c
re = /^(.+?)y$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(s_v);
if (re.test(stem))
w = stem + "i";
}
// Step 2
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step2list[suffix];
}
// Step 3
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
suffix = fp[2];
re = new RegExp(mgr0);
if (re.test(stem))
w = stem + step3list[suffix];
}
// Step 4
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
re2 = /^(.+?)(s|t)(ion)$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
if (re.test(stem))
w = stem;
}
else if (re2.test(w)) {
var fp = re2.exec(w);
stem = fp[1] + fp[2];
re2 = new RegExp(mgr1);
if (re2.test(stem))
w = stem;
}
// Step 5
re = /^(.+?)e$/;
if (re.test(w)) {
var fp = re.exec(w);
stem = fp[1];
re = new RegExp(mgr1);
re2 = new RegExp(meq1);
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
w = stem;
}
re = /ll$/;
re2 = new RegExp(mgr1);
if (re.test(w) && re2.test(w)) {
re = /.$/;
w = w.replace(re,"");
}
// and turn initial Y back to y
if (firstch == "y")
w = firstch.toLowerCase() + w.substr(1);
return w;
if (!splitQuery) {
function splitQuery(query) {
return query.split(/\s+/);
}
}
/**
* Simple result scoring code.
*/
var Scorer = {
// Implement the following function to further tweak the score for each result
// The function takes a result array [filename, title, anchor, descr, score]
// and returns the new score.
/*
score: function(result) {
return result[4];
},
*/
// query matches the full name of an object
objNameMatch: 11,
// or matches in the last dotted part of the object name
objPartialMatch: 6,
// Additive scores depending on the priority of the object
objPrio: {0: 15, // used to be importantResults
1: 5, // used to be objectResults
2: -5}, // used to be unimportantResults
// Used when the priority is not in the mapping.
objPrioDefault: 0,
// query found in title
title: 15,
// query found in terms
term: 5
};
var splitChars = (function() {
var result = {};
var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
var i, j, start, end;
for (i = 0; i < singles.length; i++) {
result[singles[i]] = true;
}
var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
[722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
[1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
[1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
[1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
[2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
[2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
[2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
[2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
[2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
[2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
[2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
[3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
[3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
[3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
[3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
[3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
[3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
[4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
[4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
[4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
[4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
[5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
[6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
[6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
[6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
[6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
[7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
[7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
[8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
[8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
[8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
[10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
[11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
[12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
[12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
[12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
[19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
[42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
[42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
[43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
[43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
[43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
[43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
[44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
[57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
[64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
[65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
[65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
for (i = 0; i < ranges.length; i++) {
start = ranges[i][0];
end = ranges[i][1];
for (j = start; j <= end; j++) {
result[j] = true;
}
}
return result;
})();
function splitQuery(query) {
var result = [];
var start = -1;
for (var i = 0; i < query.length; i++) {
if (splitChars[query.charCodeAt(i)]) {
if (start !== -1) {
result.push(query.slice(start, i));
start = -1;
}
} else if (start === -1) {
start = i;
}
}
if (start !== -1) {
result.push(query.slice(start));
}
return result;
}
/**
* Search Module
*/
@ -335,6 +58,19 @@ var Search = {
_queued_query : null,
_pulse_status : -1,
htmlToText : function(htmlString) {
var virtualDocument = document.implementation.createHTMLDocument('virtual');
var htmlElement = $(htmlString, virtualDocument);
htmlElement.find('.headerlink').remove();
docContent = htmlElement.find('[role=main]')[0];
if(docContent === undefined) {
console.warn("Content block not found. Sphinx search tries to obtain it " +
"via '[role=main]'. Could you check your theme or template.");
return "";
}
return docContent.textContent || docContent.innerText;
},
init : function() {
var params = $.getQueryParameters();
if (params.q) {
@ -399,7 +135,7 @@ var Search = {
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.status = $('<p class="search-summary">&nbsp;</p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
@ -417,7 +153,6 @@ var Search = {
*/
query : function(query) {
var i;
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
@ -431,8 +166,7 @@ var Search = {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
tmp[i] === "") {
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i] === "") {
// skip this "word"
continue;
}
@ -514,8 +248,10 @@ var Search = {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
var listItem = $('<li></li>');
var requestUrl = "";
var linkUrl = "";
if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
@ -523,44 +259,45 @@ var Search = {
} else if (dirname == 'index/') {
dirname = '';
}
listItem.append($('<a/>').attr('href',
DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
highlightstring + item[2]).html(item[1]));
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;
linkUrl = requestUrl;
} else {
// normal html builders
listItem.append($('<a/>').attr('href',
item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;
linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX;
}
listItem.append($('<a/>').attr('href',
linkUrl +
highlightstring + item[2]).html(item[1]));
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
setTimeout(function() {
displayNextItem();
});
}, 5);
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
if (suffix === undefined) {
suffix = '.txt';
}
$.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
$.ajax({url: requestUrl,
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
if (data !== '' && data !== undefined) {
listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
var summary = Search.makeSearchSummary(data, searchterms, hlterms);
if (summary) {
listItem.append(summary);
}
}
Search.output.append(listItem);
listItem.slideDown(5, function() {
setTimeout(function() {
displayNextItem();
});
}, 5);
}});
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
setTimeout(function() {
displayNextItem();
});
}, 5);
}
}
// search finished, update title and status message
@ -591,20 +328,22 @@ var Search = {
var results = [];
for (var prefix in objects) {
for (var name in objects[prefix]) {
for (var iMatch = 0; iMatch != objects[prefix].length; ++iMatch) {
var match = objects[prefix][iMatch];
var name = match[4];
var fullname = (prefix ? prefix + '.' : '') + name;
if (fullname.toLowerCase().indexOf(object) > -1) {
var fullnameLower = fullname.toLowerCase()
if (fullnameLower.indexOf(object) > -1) {
var score = 0;
var parts = fullname.split('.');
var parts = fullnameLower.split('.');
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
if (fullname == object || parts[parts.length - 1] == object) {
if (fullnameLower == object || parts[parts.length - 1] == object) {
score += Scorer.objNameMatch;
// matches in last name
} else if (parts[parts.length - 1].indexOf(object) > -1) {
score += Scorer.objPartialMatch;
}
var match = objects[prefix][name];
var objname = objnames[match[1]][2];
var title = titles[match[0]];
// If more than one term searched for, we require other words to be
@ -644,6 +383,13 @@ var Search = {
return results;
},
/**
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
*/
escapeRegExp : function(string) {
return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
},
/**
* search for full-text terms in the index
*/
@ -665,6 +411,20 @@ var Search = {
{files: terms[word], score: Scorer.term},
{files: titleterms[word], score: Scorer.title}
];
// add support for partial matches
if (word.length > 2) {
var word_regex = this.escapeRegExp(word);
for (var w in terms) {
if (w.match(word_regex) && !terms[word]) {
_o.push({files: terms[w], score: Scorer.partialTerm})
}
}
for (var w in titleterms) {
if (w.match(word_regex) && !titleterms[word]) {
_o.push({files: titleterms[w], score: Scorer.partialTitle})
}
}
}
// no match but word was a required one
if ($u.every(_o, function(o){return o.files === undefined;})) {
@ -684,7 +444,7 @@ var Search = {
for (j = 0; j < _files.length; j++) {
file = _files[j];
if (!(file in scoreMap))
scoreMap[file] = {}
scoreMap[file] = {};
scoreMap[file][word] = o.score;
}
});
@ -692,7 +452,7 @@ var Search = {
// create the mapping
for (j = 0; j < files.length; j++) {
file = files[j];
if (file in fileMap)
if (file in fileMap && fileMap[file].indexOf(word) === -1)
fileMap[file].push(word);
else
fileMap[file] = [word];
@ -704,8 +464,12 @@ var Search = {
var valid = true;
// check if all requirements are matched
if (fileMap[file].length != searchterms.length)
continue;
var filteredTermCount = // as search terms with length < 3 are discarded: ignore
searchterms.filter(function(term){return term.length > 2}).length
if (
fileMap[file].length != searchterms.length &&
fileMap[file].length != filteredTermCount
) continue;
// ensure that none of the excluded terms is in the search result
for (i = 0; i < excluded.length; i++) {
@ -736,7 +500,11 @@ var Search = {
* words. the first one is used to find the occurrence, the
* latter for highlighting it.
*/
makeSearchSummary : function(text, keywords, hlwords) {
makeSearchSummary : function(htmlText, keywords, hlwords) {
var text = Search.htmlToText(htmlText);
if (text == "") {
return null;
}
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
@ -748,7 +516,7 @@ var Search = {
var excerpt = ((start > 0) ? '...' : '') +
$.trim(text.substr(start, 240)) +
((start + 240 - text.length) ? '...' : '');
var rv = $('<div class="context"></div>').text(excerpt);
var rv = $('<p class="context"></p>').text(excerpt);
$.each(hlwords, function() {
rv = rv.highlightText(this, 'highlighted');
});
@ -758,4 +526,4 @@ var Search = {
$(document).ready(function() {
Search.init();
});
});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,20 +1,17 @@
<!DOCTYPE html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Index &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="#" />
<link rel="search" title="Search" href="search.html" />
@ -29,6 +26,8 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
@ -129,10 +128,12 @@
<li><a href="library.html#joy.library.dipdd">dipdd() (in module joy.library)</a>
</li>
<li><a href="library.html#joy.library.disenstacken">disenstacken() (in module joy.library)</a>
</li>
<li><a href="library.html#joy.library.divmod_">divmod_() (in module joy.library)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.library.divmod_">divmod_() (in module joy.library)</a>
<li><a href="stack.html#joy.utils.stack.dnd">dnd() (in module joy.utils.stack)</a>
</li>
<li><a href="library.html#joy.library.drop">drop() (in module joy.library)</a>
</li>
@ -204,13 +205,15 @@
</li>
<li><a href="library.html#joy.library.infra">infra() (in module joy.library)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.library.initialize">initialize() (in module joy.library)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.library.inscribe">inscribe() (in module joy.library)</a>
</li>
<li><a href="library.html#joy.library.inscribe_">inscribe_() (in module joy.library)</a>
</li>
<li><a href="joy.html#joy.joy.interp">interp() (in module joy.joy)</a>
</li>
<li><a href="stack.html#joy.utils.stack.iter_stack">iter_stack() (in module joy.utils.stack)</a>
</li>
@ -222,20 +225,50 @@
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="joy.html#joy.joy.joy">joy() (in module joy.joy)</a>
</li>
<li><a href="joy.html#module-joy.joy">joy.joy (module)</a>
<li>
joy.joy
<ul>
<li><a href="joy.html#module-joy.joy">module</a>
</li>
<li><a href="library.html#module-joy.library">joy.library (module)</a>
</ul></li>
<li>
joy.library
<ul>
<li><a href="library.html#module-joy.library">module</a>
</li>
</ul></li>
<li>
joy.parser
<ul>
<li><a href="parser.html#module-joy.parser">module</a>
</li>
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="parser.html#module-joy.parser">joy.parser (module)</a>
<li>
joy.utils.generated_library
<ul>
<li><a href="library.html#module-joy.utils.generated_library">module</a>
</li>
<li><a href="library.html#module-joy.utils.generated_library">joy.utils.generated_library (module)</a>
</ul></li>
<li>
joy.utils.pretty_print
<ul>
<li><a href="pretty.html#module-joy.utils.pretty_print">module</a>
</li>
<li><a href="pretty.html#module-joy.utils.pretty_print">joy.utils.pretty_print (module)</a>
</li>
<li><a href="stack.html#module-joy.utils.stack">joy.utils.stack (module)</a>
</ul></li>
<li>
joy.utils.stack
<ul>
<li><a href="stack.html#module-joy.utils.stack">module</a>
</li>
</ul></li>
</ul></td>
</tr></table>
@ -256,12 +289,27 @@
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.library.map_">map_() (in module joy.library)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.library.max_">max_() (in module joy.library)</a>
</li>
<li><a href="library.html#joy.library.min_">min_() (in module joy.library)</a>
</li>
<li>
module
<ul>
<li><a href="joy.html#module-joy.joy">joy.joy</a>
</li>
<li><a href="library.html#module-joy.library">joy.library</a>
</li>
<li><a href="parser.html#module-joy.parser">joy.parser</a>
</li>
<li><a href="library.html#module-joy.utils.generated_library">joy.utils.generated_library</a>
</li>
<li><a href="pretty.html#module-joy.utils.pretty_print">joy.utils.pretty_print</a>
</li>
<li><a href="stack.html#module-joy.utils.stack">joy.utils.stack</a>
</li>
</ul></li>
</ul></td>
</tr></table>
@ -404,11 +452,13 @@
</li>
<li><a href="library.html#joy.utils.generated_library.uncons">uncons() (in module joy.utils.generated_library)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.library.unique">unique() (in module joy.library)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.utils.generated_library.unit">unit() (in module joy.utils.generated_library)</a>
</li>
<li><a href="joy.html#joy.joy.UnknownSymbolError">UnknownSymbolError</a>
</li>
<li><a href="library.html#joy.utils.generated_library.unswons">unswons() (in module joy.utils.generated_library)</a>
</li>
@ -458,10 +508,34 @@
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
@ -469,17 +543,23 @@
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -490,7 +570,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Thun 0.4.1 Documentation &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Thun: Joy in Python" href="notebooks/Intro.html" />
@ -29,9 +28,11 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="thun-release-documentation">
<section id="thun-release-documentation">
<h1>Thun 0.4.1 Documentation<a class="headerlink" href="#thun-release-documentation" title="Permalink to this headline"></a></h1>
<p>Thun is dialect of Joy written in Python.</p>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Joy_(programming_language)">Joy</a> is a programming language created by Manfred von Thun that is easy to
@ -43,17 +44,17 @@ between Thun and the originals, other than being written in Python, is
that it works by the “Continuation-Passing Style”.</p>
<p>Joy is:</p>
<ul class="simple">
<li><a class="reference external" href="https://en.wikipedia.org/wiki/Purely_functional_programming">Purely Functional</a></li>
<li><a class="reference external" href="https://en.wikipedia.org/wiki/Stack-oriented_programming_language">Stack-based</a></li>
<li><a class="reference external" href="https://en.wikipedia.org/wiki/Concatenative_programming_language">Concatinative</a> ( See also <a class="reference external" href="http://www.concatenative.org/wiki/view/Concatenative%20language">concatenative.org</a>)</li>
<li><a class="reference internal" href="notebooks/Categorical.html"><span class="doc">Categorical</span></a></li>
<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/Purely_functional_programming">Purely Functional</a></p></li>
<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/Stack-oriented_programming_language">Stack-based</a></p></li>
<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/Concatenative_programming_language">Concatinative</a> ( See also <a class="reference external" href="http://www.concatenative.org/wiki/view/Concatenative%20language">concatenative.org</a>)</p></li>
<li><p><a class="reference internal" href="notebooks/Categorical.html"><span class="doc">Categorical</span></a></p></li>
</ul>
<p>I hope that this package is useful in the sense that it provides an
additional joy interpreter (the binary in the archive from La Trobe seems
to run just fine on my modern Linux machine!) But I also hope that you
can read and understand the Python code and play with the implementation
itself.</p>
<div class="section" id="quick-start">
<section id="quick-start">
<h2>Quick Start<a class="headerlink" href="#quick-start" title="Permalink to this headline"></a></h2>
<p>Install from <a class="reference external" href="https://pypi.org/project/Thun/">PyPI</a> in the usual way:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ pip install Thun
@ -64,17 +65,17 @@ itself.</p>
</pre></div>
</div>
<p>Continue with <a class="reference internal" href="notebooks/Intro.html"><span class="doc">the introduction</span></a>.</p>
</div>
<div class="section" id="project-hosted-on-osdn">
</section>
<section id="project-hosted-on-osdn">
<h2>Project Hosted on <a class="reference external" href="https://osdn.net/projects/joypy/">OSDN</a><a class="headerlink" href="#project-hosted-on-osdn" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><a class="reference external" href="https://osdn.net/projects/joypy/scm/hg/Joypy/tree/tip/">Source Repository</a> (Mercurial)</li>
<li><a class="reference external" href="https://osdn.net/projects/joypy/ticket/">Bug tracker</a></li>
<li><a class="reference external" href="https://osdn.net/projects/joypy/forums/">Forums</a></li>
<li><a class="reference external" href="https://osdn.net/projects/joypy/lists/">Mailing list</a></li>
<li><p><a class="reference external" href="https://osdn.net/projects/joypy/scm/hg/Joypy/tree/tip/">Source Repository</a> (Mercurial)</p></li>
<li><p><a class="reference external" href="https://osdn.net/projects/joypy/ticket/">Bug tracker</a></p></li>
<li><p><a class="reference external" href="https://osdn.net/projects/joypy/forums/">Forums</a></p></li>
<li><p><a class="reference external" href="https://osdn.net/projects/joypy/lists/">Mailing list</a></p></li>
</ul>
</div>
<div class="section" id="information-on-the-joy-language">
</section>
<section id="information-on-the-joy-language">
<h2>Information on the Joy language<a class="headerlink" href="#information-on-the-joy-language" title="Permalink to this headline"></a></h2>
<p>See <a class="reference external" href="https://en.wikipedia.org/wiki/Joy_(programming_language)">the Wikipedia article</a> and <a class="reference external" href="http://www.kevinalbrecht.com/code/joy-mirror/index.html">Kevin Albrechts mirror of Manfred von Thuns original website for the Joy Programming Language</a> for more information on the Joy language.</p>
<p>The best source (no pun intended) for learning about Joy is the
@ -84,8 +85,8 @@ original C interpreter, Joy language source code for various functions,
and a great deal of fascinating material mostly written by Von Thun on
Joy and its deeper facets as well as how to program in it and several
interesting aspects. Its quite a treasure trove.</p>
</div>
<div class="section" id="documentation-on-thun-dialect">
</section>
<section id="documentation-on-thun-dialect">
<h2>Documentation on Thun Dialect<a class="headerlink" href="#documentation-on-thun-dialect" title="Permalink to this headline"></a></h2>
<p>The following is specific information for this dialect of Joy.</p>
<div class="toctree-wrapper compound">
@ -155,34 +156,46 @@ interesting aspects. Its quite a treasure trove.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="section" id="indices-and-tables">
</section>
</section>
<section id="indices-and-tables">
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h1>
<ul class="simple">
<li><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></li>
<li><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></li>
<li><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></li>
<li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li>
<li><p><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></p></li>
<li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li>
</ul>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="#">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Thun 0.4.1 Documentation</a><ul>
<li><a class="reference internal" href="#quick-start">Quick Start</a></li>
<li><a class="reference internal" href="#project-hosted-on-osdn">Project Hosted on OSDN</a></li>
<li><a class="reference internal" href="#information-on-the-joy-language">Information on the Joy language</a></li>
<li><a class="reference internal" href="#documentation-on-thun-dialect">Documentation on Thun Dialect</a></li>
</ul>
</li>
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
<h1 class="logo"><a href="#">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -191,25 +204,24 @@ interesting aspects. Its quite a treasure trove.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/index.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -220,7 +232,7 @@ interesting aspects. Its quite a treasure trove.</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Joy Interpreter &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Stack or Quote or Sequence or List…" href="stack.html" />
@ -30,105 +29,131 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="joy-interpreter">
<section id="joy-interpreter">
<h1>Joy Interpreter<a class="headerlink" href="#joy-interpreter" title="Permalink to this headline"></a></h1>
<div class="section" id="module-joy.joy">
<section id="module-joy.joy">
<span id="joy-joy"></span><h2><code class="docutils literal notranslate"><span class="pre">joy.joy</span></code><a class="headerlink" href="#module-joy.joy" title="Permalink to this headline"></a></h2>
<p>This module implements an interpreter for a dialect of Joy that
attempts to stay very close to the spirit of Joy but does not precisely
match the behaviour of the original version(s) written in C.</p>
<dl class="function">
<dt id="joy.joy.joy">
<code class="descclassname">joy.joy.</code><code class="descname">joy</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em>, <em>viewer=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#joy"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.joy.joy" title="Permalink to this definition"></a></dt>
<dl class="py exception">
<dt class="sig sig-object py" id="joy.joy.UnknownSymbolError">
<em class="property"><span class="pre">exception</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">joy.joy.</span></span><span class="sig-name descname"><span class="pre">UnknownSymbolError</span></span><a class="reference internal" href="_modules/joy/joy.html#UnknownSymbolError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.joy.UnknownSymbolError" title="Permalink to this definition"></a></dt>
<dd></dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="joy.joy.interp">
<span class="sig-prename descclassname"><span class="pre">joy.joy.</span></span><span class="sig-name descname"><span class="pre">interp</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">stack</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">()</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">dictionary</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#interp"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.joy.interp" title="Permalink to this definition"></a></dt>
<dd><p>Simple REPL with no extra output, suitable for use in scripts.</p>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="joy.joy.joy">
<span class="sig-prename descclassname"><span class="pre">joy.joy.</span></span><span class="sig-name descname"><span class="pre">joy</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">stack</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">expression</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">dictionary</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">viewer</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#joy"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.joy.joy" title="Permalink to this definition"></a></dt>
<dd><p>Evaluate a Joy expression on a stack.</p>
<p>This function iterates through a sequence of terms which are either
literals (strings, numbers, sequences of terms) or function symbols.
Literals are put onto the stack and functions are looked up in the
disctionary and executed.</p>
<p>The viewer is a function that is called with the stack and expression
dictionary and executed.</p>
<blockquote>
<div><p>The viewer is a function that is called with the stack and expression
on every iteration, its return value is ignored.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>stack</strong> (<em>stack</em>) The stack.</li>
<li><strong>expression</strong> (<em>stack</em>) The expression to evaluate.</li>
<li><strong>dictionary</strong> (<em>dict</em>) A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</li>
<li><strong>viewer</strong> (<em>function</em>) Optional viewer function.</li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">(stack, (), dictionary)</p>
</td>
</tr>
</tbody>
</table>
<dl class="field-list simple">
<dt class="field-odd">param stack stack</dt>
<dd class="field-odd"><p>The stack.</p>
</dd>
<dt class="field-even">param stack expression</dt>
<dd class="field-even"><p>The expression to evaluate.</p>
</dd>
<dt class="field-odd">param dict dictionary</dt>
<dd class="field-odd"><p>A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</p>
</dd>
<dt class="field-even">param function viewer</dt>
<dd class="field-even"><p>Optional viewer function.</p>
</dd>
<dt class="field-odd">rtype</dt>
<dd class="field-odd"><p>(stack, (), dictionary)</p>
</dd>
</dl>
</div></blockquote>
</dd></dl>
<dl class="function">
<dt id="joy.joy.repl">
<code class="descclassname">joy.joy.</code><code class="descname">repl</code><span class="sig-paren">(</span><em>stack=()</em>, <em>dictionary=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#repl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.joy.repl" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.joy.repl">
<span class="sig-prename descclassname"><span class="pre">joy.joy.</span></span><span class="sig-name descname"><span class="pre">repl</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">stack</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">()</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">dictionary</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#repl"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.joy.repl" title="Permalink to this definition"></a></dt>
<dd><p>Read-Evaluate-Print Loop</p>
<p>Accept input and run it on the stack, loop.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>stack</strong> (<em>stack</em>) The stack.</li>
<li><strong>dictionary</strong> (<em>dict</em>) A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</li>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>stack</strong> (<em>stack</em>) The stack.</p></li>
<li><p><strong>dictionary</strong> (<em>dict</em>) A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</p></li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">stack</p>
</td>
</tr>
</tbody>
</table>
</dd>
<dt class="field-even">Return type</dt>
<dd class="field-even"><p>stack</p>
</dd>
</dl>
</dd></dl>
<dl class="function">
<dt id="joy.joy.run">
<code class="descclassname">joy.joy.</code><code class="descname">run</code><span class="sig-paren">(</span><em>text</em>, <em>stack</em>, <em>dictionary</em>, <em>viewer=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#run"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.joy.run" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.joy.run">
<span class="sig-prename descclassname"><span class="pre">joy.joy.</span></span><span class="sig-name descname"><span class="pre">run</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">text</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stack</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">dictionary</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">viewer</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#run"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.joy.run" title="Permalink to this definition"></a></dt>
<dd><p>Return the stack resulting from running the Joy code text on the stack.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>text</strong> (<em>str</em>) Joy code.</li>
<li><strong>stack</strong> (<em>stack</em>) The stack.</li>
<li><strong>dictionary</strong> (<em>dict</em>) A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</li>
<li><strong>viewer</strong> (<em>function</em>) Optional viewer function.</li>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>text</strong> (<em>str</em>) Joy code.</p></li>
<li><p><strong>stack</strong> (<em>stack</em>) The stack.</p></li>
<li><p><strong>dictionary</strong> (<em>dict</em>) A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</p></li>
<li><p><strong>viewer</strong> (<em>function</em>) Optional viewer function.</p></li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">(stack, (), dictionary)</p>
</td>
</tr>
</tbody>
</table>
</dd>
<dt class="field-even">Return type</dt>
<dd class="field-even"><p>(stack, (), dictionary)</p>
</dd>
</dl>
</dd></dl>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Joy Interpreter</a><ul>
<li><a class="reference internal" href="#module-joy.joy"><code class="docutils literal notranslate"><span class="pre">joy.joy</span></code></a></li>
<h1 class="logo"><a href="index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Joy Interpreter</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#module-joy.joy"><code class="docutils literal notranslate"><span class="pre">joy.joy</span></code></a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -138,25 +163,24 @@ on every iteration, its return value is ignored.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/joy.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -167,7 +191,7 @@ on every iteration, its return value is ignored.</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Categorical Programming &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="The Four Fundamental Operations of Definite Action" href="The_Four_Operations.html" />
@ -30,25 +29,69 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="categorical-programming">
<section id="categorical-programming">
<h1>Categorical Programming<a class="headerlink" href="#categorical-programming" title="Permalink to this headline"></a></h1>
<p>DRAFT</p>
<p><a class="reference external" href="https://en.wikipedia.org/wiki/Category_theory">Categorical</a></p>
<p>In Manfred von Thuns article <a class="reference external" href="http://www.kevinalbrecht.com/code/joy-mirror/j08cnt.html">Joy compared with other functional languages</a> he asks, “Could the language of categories be used for writing programs? Any lambda expression can be translated into a categorical expression, so the language of categories is expressively complete. But this does not make it a suitable language for writing programs. As it stands it is a very low-level language.”</p>
<p>In <a class="reference external" href="http://conal.net/papers/compiling-to-categories/">Compiling to categories</a> Conal Elliott give a taste of what this might mean.</p>
<blockquote>
<div>It is well-known that the simply typed lambda-calculus is modeled by any cartesian closed category (CCC). This correspondence suggests giving typed functional programs a variety of interpretations, each corresponding to a different category. A convenient way to realize this idea is as a collection of meaning-preserving transformations added to an existing compiler, such as GHC for Haskell. This paper describes such an implementation and demonstrates its use for a variety of interpretations including hardware circuits, automatic differentiation, incremental computation, and interval analysis. Each such interpretation is a category easily defined in Haskell (outside of the compiler). The general technique appears to provide a compelling alternative to deeply embedded domain-specific languages.</div></blockquote>
<div><p>It is well-known that the simply typed lambda-calculus is modeled by any cartesian closed category (CCC). This correspondence suggests giving typed functional programs a variety of interpretations, each corresponding to a different category. A convenient way to realize this idea is as a collection of meaning-preserving transformations added to an existing compiler, such as GHC for Haskell. This paper describes such an implementation and demonstrates its use for a variety of interpretations including hardware circuits, automatic differentiation, incremental computation, and interval analysis. Each such interpretation is a category easily defined in Haskell (outside of the compiler). The general technique appears to provide a compelling alternative to deeply embedded domain-specific languages.</p>
</div></blockquote>
<p>What hes doing is translating lambda forms into a kind of “point-free” style that is very close to Joy code (although more verbose) and then showing how to instantiate that code over different categories to get several different kinds of program out of the same code.</p>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
@ -59,25 +102,24 @@
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Categorical.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -88,7 +130,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Thun: Joy in Python &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Joy Interpreter" href="../joy.html" />
@ -30,20 +29,22 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="thun-joy-in-python">
<section id="thun-joy-in-python">
<h1>Thun: Joy in Python<a class="headerlink" href="#thun-joy-in-python" title="Permalink to this headline"></a></h1>
<p>This implementation is meant as a tool for exploring the programming
model and method of Joy. Python seems like a great implementation
language for Joy for several reasons.</p>
<ul class="simple">
<li>We can lean on the Python immutable types for our basic semantics and types: ints, floats, strings, and tuples, which enforces functional purity.</li>
<li>We get garbage collection for free.</li>
<li>Compilation via Cython.</li>
<li>Python is a “glue language” with loads of libraries which we can wrap in Joy functions.</li>
<li><p>We can lean on the Python immutable types for our basic semantics and types: ints, floats, strings, and tuples, which enforces functional purity.</p></li>
<li><p>We get garbage collection for free.</p></li>
<li><p>Compilation via Cython.</p></li>
<li><p>Python is a “glue language” with loads of libraries which we can wrap in Joy functions.</p></li>
</ul>
<div class="section" id="read-eval-print-loop-repl">
<section id="read-eval-print-loop-repl">
<h2><a class="reference external" href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">Read-Eval-Print Loop (REPL)</a><a class="headerlink" href="#read-eval-print-loop-repl" title="Permalink to this headline"></a></h2>
<p>The main way to interact with the Joy interpreter is through a simple
<a class="reference external" href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">REPL</a>
@ -86,8 +87,8 @@ joy?
joy?
</pre></div>
</div>
</div>
<div class="section" id="the-stack">
</section>
<section id="the-stack">
<h2>The Stack<a class="headerlink" href="#the-stack" title="Permalink to this headline"></a></h2>
<p>In Joy, in addition to the types Boolean, integer, float, and string,
there is a <a class="reference internal" href="../stack.html"><span class="doc">single sequence type</span></a> represented by enclosing a sequence of
@ -95,21 +96,21 @@ terms in brackets <code class="docutils literal notranslate"><span class="pre">[
both the stack and the expression. It is a <a class="reference external" href="https://en.wikipedia.org/wiki/Cons#Lists">cons
list</a> made from Python
tuples.</p>
</div>
<div class="section" id="purely-functional-datastructures">
</section>
<section id="purely-functional-datastructures">
<h2>Purely Functional Datastructures<a class="headerlink" href="#purely-functional-datastructures" title="Permalink to this headline"></a></h2>
<p>Because Joy stacks are made out of Python tuples they are immutable, as are the other Python types we “borrow” for Joy, so all Joy datastructures are <a class="reference external" href="https://en.wikipedia.org/wiki/Purely_functional_data_structure">purely functional</a>.</p>
</div>
<div class="section" id="the-joy-function">
</section>
<section id="the-joy-function">
<h2>The <code class="docutils literal notranslate"><span class="pre">joy()</span></code> function<a class="headerlink" href="#the-joy-function" title="Permalink to this headline"></a></h2>
<div class="section" id="an-interpreter">
<section id="an-interpreter">
<h3>An Interpreter<a class="headerlink" href="#an-interpreter" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">joy()</span></code> interpreter function is extrememly simple. It accepts a stack, an
expression, and a dictionary, and it iterates through the expression
putting values onto the stack and delegating execution to functions which it
looks up in the dictionary.</p>
</div>
<div class="section" id="continuation-passing-style">
</section>
<section id="continuation-passing-style">
<h3><a class="reference external" href="https://en.wikipedia.org/wiki/Continuation-passing_style">Continuation-Passing Style</a><a class="headerlink" href="#continuation-passing-style" title="Permalink to this headline"></a></h3>
<p>One day I thought, What happens if you rewrite Joy to use
<a class="reference external" href="https://en.wikipedia.org/wiki/Continuation-passing_style">CPS</a>? I
@ -117,8 +118,8 @@ made all the functions accept and return the expression as well as the
stack and found that all the combinators could be rewritten to work by
modifying the expression rather than making recursive calls to the
<code class="docutils literal notranslate"><span class="pre">joy()</span></code> function.</p>
</div>
<div class="section" id="view-function">
</section>
<section id="view-function">
<h3>View function<a class="headerlink" href="#view-function" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">joy()</span></code> function accepts an optional <code class="docutils literal notranslate"><span class="pre">viewer</span></code> argument that
is a function which it calls on
@ -127,70 +128,70 @@ evaluation. This can be used for tracing, breakpoints, retrying after
exceptions, or interrupting an evaluation and saving to disk or sending
over the network to resume later. The stack and expression together
contain all the state of the computation at each step.</p>
</div>
<div class="section" id="the-traceprinter">
</section>
<section id="the-traceprinter">
<h3>The <code class="docutils literal notranslate"><span class="pre">TracePrinter</span></code>.<a class="headerlink" href="#the-traceprinter" title="Permalink to this headline"></a></h3>
<p>A <code class="docutils literal notranslate"><span class="pre">viewer</span></code> records each step of the evaluation of a Joy program. The
<code class="docutils literal notranslate"><span class="pre">TracePrinter</span></code> has a facility for printing out a trace of the
evaluation, one line per step. Each step is aligned to the current
interpreter position, signified by a period separating the stack on the
left from the pending expression (“continuation”) on the right.</p>
</div>
</div>
<div class="section" id="parser">
</section>
</section>
<section id="parser">
<h2>Parser<a class="headerlink" href="#parser" title="Permalink to this headline"></a></h2>
<p>The parser is extremely simple. The undocumented <code class="docutils literal notranslate"><span class="pre">re.Scanner</span></code> class
does the tokenizing and then the parser builds the tuple
structure out of the tokens. Theres no Abstract Syntax Tree or anything
like that.</p>
<div class="section" id="symbols">
<section id="symbols">
<h3>Symbols<a class="headerlink" href="#symbols" title="Permalink to this headline"></a></h3>
<p>TODO: Symbols are just a string subclass; used by the parser to represent function names and by the interpreter to look up functions in the dictionary. N.B.: Symbols are not looked up at parse-time. You <em>could</em> define recursive functions, er, recusively, without <code class="docutils literal notranslate"><span class="pre">genrec</span></code> or other recursion combinators <code class="docutils literal notranslate"><span class="pre">foo</span> <span class="pre">==</span> <span class="pre">...</span> <span class="pre">foo</span> <span class="pre">...</span></code> but dont do that.</p>
</div>
<div class="section" id="token-regular-expressions">
</section>
<section id="token-regular-expressions">
<h3>Token Regular Expressions<a class="headerlink" href="#token-regular-expressions" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">123</span> <span class="mf">1.2</span> <span class="s1">&#39;single quotes&#39;</span> <span class="s2">&quot;double quotes&quot;</span> <span class="n">function</span>
</pre></div>
</div>
<p>TBD (look in the :module: joy.parser module.)</p>
</div>
<div class="section" id="examples">
</section>
<section id="examples">
<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline"></a></h3>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;1 2 3 4 5&#39;</span><span class="p">)</span> <span class="c1"># A simple sequence.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>joy.parser.text_to_expression(&#39;1 2 3 4 5&#39;) # A simple sequence.
</pre></div>
</div>
<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="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="p">())))))</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;[1 2 3] 4 5&#39;</span><span class="p">)</span> <span class="c1"># Three items, the first is a list with three items</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>joy.parser.text_to_expression(&#39;[1 2 3] 4 5&#39;) # Three items, the first is a list with three items
</pre></div>
</div>
<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="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">()))),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="p">())))</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;1 23 [&quot;four&quot; [-5.0] cons] 8888&#39;</span><span class="p">)</span> <span class="c1"># A mixed bag. cons is</span>
<span class="c1"># a Symbol, no lookup at</span>
<span class="c1"># parse-time. Haiku docs.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>joy.parser.text_to_expression(&#39;1 23 [&quot;four&quot; [-5.0] cons] 8888&#39;) # A mixed bag. cons is
# a Symbol, no lookup at
# parse-time. Haiku docs.
</pre></div>
</div>
<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="mi">23</span><span class="p">,</span> <span class="p">((</span><span class="s1">&#39;four&#39;</span><span class="p">,</span> <span class="p">((</span><span class="o">-</span><span class="mf">5.0</span><span class="p">,</span> <span class="p">()),</span> <span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="p">()))),</span> <span class="p">(</span><span class="mi">8888</span><span class="p">,</span> <span class="p">()))))</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;[][][][][]&#39;</span><span class="p">)</span> <span class="c1"># Five empty lists.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>joy.parser.text_to_expression(&#39;[][][][][]&#39;) # Five empty lists.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((),</span> <span class="p">((),</span> <span class="p">((),</span> <span class="p">((),</span> <span class="p">((),</span> <span class="p">())))))</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;[[[[[]]]]]&#39;</span><span class="p">)</span> <span class="c1"># Five nested lists.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>joy.parser.text_to_expression(&#39;[[[[[]]]]]&#39;) # Five nested lists.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((((((),</span> <span class="p">()),</span> <span class="p">()),</span> <span class="p">()),</span> <span class="p">()),</span> <span class="p">())</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="library">
</section>
</section>
<section id="library">
<h2>Library<a class="headerlink" href="#library" title="Permalink to this headline"></a></h2>
<p>The Joy library of functions (aka commands, or “words” after Forth
usage) encapsulates all the actual functionality (no pun intended) of
@ -198,7 +199,7 @@ the Joy system. There are simple functions such as addition <code class="docutil
<code class="docutils literal notranslate"><span class="pre">+</span></code>, the library module supports aliases), and combinators which
provide control-flow and higher-order operations.</p>
<p>Many of the functions are defined in Python, like <code class="docutils literal notranslate"><span class="pre">dip</span></code>:</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">inspect</span><span class="o">.</span><span class="n">getsource</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>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>print inspect.getsource(joy.library.dip)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">dip</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
@ -211,11 +212,10 @@ provide control-flow and higher-order operations.</p>
When the interpreter executes a definition function that function just
pushes its body expression onto the pending expression (the
continuation) and returns control to the interpreter.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">definitions</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>print joy.library.definitions
</pre></div>
</div>
<pre class="literal-block">
second == rest first
<pre class="literal-block">second == rest first
third == rest rest first
product == 1 swap [*] step
swons == swap cons
@ -248,8 +248,7 @@ anamorphism == [pop []] swap [dip swons] genrec
range == [0 &lt;=] [1 - dup] anamorphism
while == swap [nullary] cons dup dipd concat loop
dudipd == dup dipd
primrec == [i] genrec
</pre>
primrec == [i] genrec</pre>
<p>Currently, theres no function to add new definitions to the dictionary
from “within” Joy code itself. Adding new definitions remains a
meta-interpreter action. You have to do it yourself, in Python, and wash
@ -260,7 +259,7 @@ stack and expression. Theres an implicit <em>standard dictionary</em> that
defines the actual semantics of the syntactic stack and expression
datastructures (which only contain symbols, not the actual functions.
Pickle some and see for yourself.)</p>
<div class="section" id="there-should-be-only-one">
<section id="there-should-be-only-one">
<h3>“There should be only one.”<a class="headerlink" href="#there-should-be-only-one" title="Permalink to this headline"></a></h3>
<p>Which brings me to talking about one of my hopes and dreams for this
notation: “There should be only one.” What I mean is that there should
@ -277,8 +276,8 @@ frameworks, programming languages. Its a waste of time, a <a class="reference
“thundering herd”
attack</a> on
human mentality.</p>
</div>
<div class="section" id="literary-code-library">
</section>
<section id="literary-code-library">
<h3>Literary Code Library<a class="headerlink" href="#literary-code-library" title="Permalink to this headline"></a></h3>
<p>If you read over the other notebooks youll see that developing code in
Joy is a lot like doing simple mathematics, and the descriptions of the
@ -292,43 +291,47 @@ card is highly desirable. Less code has fewer errors. The structure of
Joy engenders a kind of thinking that seems to be very effective for
developing structured processes.</p>
<p>There seems to be an elegance and power to the notation.</p>
</div>
</div>
</div>
</section>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Thun: Joy in Python</a><ul>
<li><a class="reference internal" href="#read-eval-print-loop-repl">Read-Eval-Print Loop (REPL)</a></li>
<li><a class="reference internal" href="#the-stack">The Stack</a></li>
<li><a class="reference internal" href="#purely-functional-datastructures">Purely Functional Datastructures</a></li>
<li><a class="reference internal" href="#the-joy-function">The <code class="docutils literal notranslate"><span class="pre">joy()</span></code> function</a><ul>
<li><a class="reference internal" href="#an-interpreter">An Interpreter</a></li>
<li><a class="reference internal" href="#continuation-passing-style">Continuation-Passing Style</a></li>
<li><a class="reference internal" href="#view-function">View function</a></li>
<li><a class="reference internal" href="#the-traceprinter">The <code class="docutils literal notranslate"><span class="pre">TracePrinter</span></code>.</a></li>
</ul>
</li>
<li><a class="reference internal" href="#parser">Parser</a><ul>
<li><a class="reference internal" href="#symbols">Symbols</a></li>
<li><a class="reference internal" href="#token-regular-expressions">Token Regular Expressions</a></li>
<li><a class="reference internal" href="#examples">Examples</a></li>
</ul>
</li>
<li><a class="reference internal" href="#library">Library</a><ul>
<li><a class="reference internal" href="#there-should-be-only-one">“There should be only one.”</a></li>
<li><a class="reference internal" href="#literary-code-library">Literary Code Library</a></li>
</ul>
</li>
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Thun: Joy in Python</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#read-eval-print-loop-repl">Read-Eval-Print Loop (REPL)</a></li>
<li class="toctree-l2"><a class="reference internal" href="#the-stack">The Stack</a></li>
<li class="toctree-l2"><a class="reference internal" href="#purely-functional-datastructures">Purely Functional Datastructures</a></li>
<li class="toctree-l2"><a class="reference internal" href="#the-joy-function">The <code class="docutils literal notranslate"><span class="pre">joy()</span></code> function</a></li>
<li class="toctree-l2"><a class="reference internal" href="#parser">Parser</a></li>
<li class="toctree-l2"><a class="reference internal" href="#library">Library</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -338,25 +341,24 @@ developing structured processes.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Intro.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -367,7 +369,7 @@ developing structured processes.</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Newtons method &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script defer="defer" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Traversing Datastructures with Zippers" href="Zipper.html" />
@ -30,18 +30,20 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="newton-s-method">
<section id="newton-s-method">
<h1><a class="reference external" href="https://en.wikipedia.org/wiki/Newton%27s_method">Newtons method</a><a class="headerlink" href="#newton-s-method" title="Permalink to this headline"></a></h1>
<p>Lets use the Newton-Raphson method for finding the root of an equation
to write a function that can compute the square root of a number.</p>
<p>Cf. <a class="reference external" href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">“Why Functional Programming Matters” by John
Hughes</a></p>
<div class="code ipython3 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">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>from notebook_preamble import J, V, define
</pre></div>
</div>
<div class="section" id="a-generator-for-approximations">
<section id="a-generator-for-approximations">
<h2>A Generator for Approximations<a class="headerlink" href="#a-generator-for-approximations" title="Permalink to this headline"></a></h2>
<p>To make a generator that generates successive approximations lets start
by assuming an initial approximation and then derive the function that
@ -51,7 +53,7 @@ computes the next approximation:</p>
<span class="n">a</span><span class="s1">&#39;</span>
</pre></div>
</div>
<div class="section" id="a-function-to-compute-the-next-approximation">
<section id="a-function-to-compute-the-next-approximation">
<h3>A Function to Compute the Next Approximation<a class="headerlink" href="#a-function-to-compute-the-next-approximation" title="Permalink to this headline"></a></h3>
<p>This is the equation for computing the next approximate value of the
square root:</p>
@ -67,8 +69,8 @@ square root:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">==</span> <span class="n">n</span> <span class="n">over</span> <span class="o">/</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span>
</pre></div>
</div>
</div>
<div class="section" id="make-it-into-a-generator">
</section>
<section id="make-it-into-a-generator">
<h3>Make it into a Generator<a class="headerlink" href="#make-it-into-a-generator" title="Permalink to this headline"></a></h3>
<p>Our generator would be created by:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="p">[</span><span class="n">dup</span> <span class="n">F</span><span class="p">]</span> <span class="n">make_generator</span>
@ -90,10 +92,10 @@ function were writing. If we let 1 be the initial approximation:</p>
<span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="mi">23</span> <span class="n">over</span> <span class="o">/</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span><span class="p">]</span> <span class="n">make_generator</span>
</pre></div>
</div>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;gsra 1 swap [over / + 2 /] cons [dup] swoncat make_generator&#39;</span><span class="p">)</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>define(&#39;gsra 1 swap [over / + 2 /] cons [dup] swoncat make_generator&#39;)
</pre></div>
</div>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;23 gsra&#39;</span><span class="p">)</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>J(&#39;23 gsra&#39;)
</pre></div>
</div>
<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="n">dup</span> <span class="mi">23</span> <span class="n">over</span> <span class="o">/</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span>
@ -101,23 +103,24 @@ function were writing. If we let 1 be the initial approximation:</p>
</div>
<p>Lets drive the generator a few time (with the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator) and
square the approximation to see how well it works…</p>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;23 gsra 6 [x popd] times first sqr&#39;</span><span class="p">)</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>J(&#39;23 gsra 6 [x popd] times first sqr&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">23.0000000001585</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="finding-consecutive-approximations-within-a-tolerance">
</section>
</section>
<section id="finding-consecutive-approximations-within-a-tolerance">
<h2>Finding Consecutive Approximations within a Tolerance<a class="headerlink" href="#finding-consecutive-approximations-within-a-tolerance" title="Permalink to this headline"></a></h2>
<p>From <a class="reference external" href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">“Why Functional Programming Matters” by John
Hughes</a>:</p>
<blockquote>
<div>The remainder of a square root finder is a function <em>within</em>, which
<div><p>The remainder of a square root finder is a function <em>within</em>, which
takes a tolerance and a list of approximations and looks down the
list for two successive approximations that differ by no more than
the given tolerance.</div></blockquote>
the given tolerance.</p>
</div></blockquote>
<p>(And note that by “list” he means a lazily-evaluated list.)</p>
<p>Using the <em>output</em> <code class="docutils literal notranslate"><span class="pre">[a</span> <span class="pre">G]</span></code> of the above generator for square root
approximations, and further assuming that the first term a has been
@ -132,7 +135,7 @@ generated already and epsilon ε is handy on the stack…</p>
<span class="n">b</span> <span class="p">[</span><span class="n">c</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">within</span>
</pre></div>
</div>
<div class="section" id="predicate">
<section id="predicate">
<h3>Predicate<a class="headerlink" href="#predicate" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="p">[</span><span class="n">first</span> <span class="o">-</span> <span class="nb">abs</span><span class="p">]</span> <span class="n">dip</span> <span class="o">&lt;=</span>
<span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">first</span> <span class="o">-</span> <span class="nb">abs</span> <span class="n">ε</span> <span class="o">&lt;=</span>
@ -142,11 +145,11 @@ generated already and epsilon ε is handy on the stack…</p>
<span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">a</span><span class="o">-</span><span class="n">b</span><span class="p">)</span><span class="o">&lt;=</span><span class="n">ε</span><span class="p">)</span>
</pre></div>
</div>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;_within_P [first - abs] dip &lt;=&#39;</span><span class="p">)</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>define(&#39;_within_P [first - abs] dip &lt;=&#39;)
</pre></div>
</div>
</div>
<div class="section" id="base-case">
</section>
<section id="base-case">
<h3>Base-Case<a class="headerlink" href="#base-case" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">roll</span><span class="o">&lt;</span> <span class="n">popop</span> <span class="n">first</span>
<span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">a</span> <span class="n">popop</span> <span class="n">first</span>
@ -154,19 +157,19 @@ generated already and epsilon ε is handy on the stack…</p>
<span class="n">b</span>
</pre></div>
</div>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;_within_B roll&lt; popop first&#39;</span><span class="p">)</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>define(&#39;_within_B roll&lt; popop first&#39;)
</pre></div>
</div>
</div>
<div class="section" id="recur">
</section>
<section id="recur">
<h3>Recur<a class="headerlink" href="#recur" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">R0</span> <span class="p">[</span><span class="n">within</span><span class="p">]</span> <span class="n">R1</span>
</pre></div>
</div>
<ol class="arabic simple">
<li>Discard a.</li>
<li>Use <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator to generate next term from <code class="docutils literal notranslate"><span class="pre">G</span></code>.</li>
<li>Run <code class="docutils literal notranslate"><span class="pre">within</span></code> with <code class="docutils literal notranslate"><span class="pre">i</span></code> (it is a “tail-recursive” function.)</li>
<li><p>Discard a.</p></li>
<li><p>Use <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator to generate next term from <code class="docutils literal notranslate"><span class="pre">G</span></code>.</p></li>
<li><p>Run <code class="docutils literal notranslate"><span class="pre">within</span></code> with <code class="docutils literal notranslate"><span class="pre">i</span></code> (it is a “tail-recursive” function.)</p></li>
</ol>
<p>Pretty straightforward:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">R0</span> <span class="p">[</span><span class="n">within</span><span class="p">]</span> <span class="n">R1</span>
@ -179,11 +182,11 @@ generated already and epsilon ε is handy on the stack…</p>
<span class="n">b</span> <span class="p">[</span><span class="n">c</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">within</span>
</pre></div>
</div>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;_within_R [popd x] dip&#39;</span><span class="p">)</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>define(&#39;_within_R [popd x] dip&#39;)
</pre></div>
</div>
</div>
<div class="section" id="setting-up">
</section>
<section id="setting-up">
<h3>Setting up<a class="headerlink" href="#setting-up" title="Permalink to this headline"></a></h3>
<p>The recursive function we have defined so far needs a slight preamble:
<code class="docutils literal notranslate"><span class="pre">x</span></code> to prime the generator and the epsilon value to use:</p>
@ -191,66 +194,88 @@ generated already and epsilon ε is handy on the stack…</p>
<span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="o">...</span>
</pre></div>
</div>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;within x 0.000000001 [_within_P] [_within_B] [_within_R] tailrec&#39;</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">&#39;sqrt gsra within&#39;</span><span class="p">)</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>define(&#39;within x 0.000000001 [_within_P] [_within_B] [_within_R] tailrec&#39;)
define(&#39;sqrt gsra within&#39;)
</pre></div>
</div>
<p>Try it out…</p>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;36 sqrt&#39;</span><span class="p">)</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>J(&#39;36 sqrt&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">6.0</span>
</pre></div>
</div>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;23 sqrt&#39;</span><span class="p">)</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>J(&#39;23 sqrt&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span>
</pre></div>
</div>
<p>Check it.</p>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span><span class="o">**</span><span class="mi">2</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>4.795831523312719**2
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">22.999999999999996</span>
</pre></div>
</div>
<div class="code ipython3 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">math</span> <span class="k">import</span> <span class="n">sqrt</span>
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span>from math import sqrt
<span class="n">sqrt</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span>
sqrt(23)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span>
</pre></div>
</div>
</div>
</div>
</div>
</section>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Newtons method</a><ul>
<li><a class="reference internal" href="#a-generator-for-approximations">A Generator for Approximations</a><ul>
<li><a class="reference internal" href="#a-function-to-compute-the-next-approximation">A Function to Compute the Next Approximation</a></li>
<li><a class="reference internal" href="#make-it-into-a-generator">Make it into a Generator</a></li>
</ul>
</li>
<li><a class="reference internal" href="#finding-consecutive-approximations-within-a-tolerance">Finding Consecutive Approximations within a Tolerance</a><ul>
<li><a class="reference internal" href="#predicate">Predicate</a></li>
<li><a class="reference internal" href="#base-case">Base-Case</a></li>
<li><a class="reference internal" href="#recur">Recur</a></li>
<li><a class="reference internal" href="#setting-up">Setting up</a></li>
</ul>
</li>
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -262,25 +287,24 @@ generated already and epsilon ε is handy on the stack…</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Newton-Raphson.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -291,7 +315,7 @@ generated already and epsilon ε is handy on the stack…</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>No Updates &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Categorical Programming" href="Categorical.html" />
@ -30,39 +29,82 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="no-updates">
<section id="no-updates">
<h1>No Updates<a class="headerlink" href="#no-updates" title="Permalink to this headline"></a></h1>
<p>DRAFT</p>
<ol class="arabic simple">
<li>Joy doesnt need to change.</li>
<li><p>Joy doesnt need to change.</p></li>
</ol>
<blockquote>
<div><ol class="upperalpha simple">
<li>The interpreter doesnt need to change, <code class="docutils literal notranslate"><span class="pre">viewer</span></code> function can customize mainloop. Or use a sub-interpreter (Joy in Joy.) The base interpreter remains static.</li>
<li>Once a function has been named and defined <em>never change that name</em>. Its just not allowed. If you need to change a function <code class="docutils literal notranslate"><span class="pre">foo</span></code> you have to call it <code class="docutils literal notranslate"><span class="pre">foo_II</span></code> or something. Once a function (name mapped to behavior) is released to the public <em>thats it</em>, its done.</li>
<li>The language evolves by adding new definitions and refactoring, always choosing new names for new functions.</li>
<li><p>The interpreter doesnt need to change, <code class="docutils literal notranslate"><span class="pre">viewer</span></code> function can customize mainloop. Or use a sub-interpreter (Joy in Joy.) The base interpreter remains static.</p></li>
<li><p>Once a function has been named and defined <em>never change that name</em>. Its just not allowed. If you need to change a function <code class="docutils literal notranslate"><span class="pre">foo</span></code> you have to call it <code class="docutils literal notranslate"><span class="pre">foo_II</span></code> or something. Once a function (name mapped to behavior) is released to the public <em>thats it</em>, its done.</p></li>
<li><p>The language evolves by adding new definitions and refactoring, always choosing new names for new functions.</p></li>
</ol>
</div></blockquote>
<ol class="arabic simple" start="2">
<li>Following <a class="reference external" href="https://semver.org">Semantic Versioning</a> there will never be a version 2.0.</li>
<li><p>Following <a class="reference external" href="https://semver.org">Semantic Versioning</a> there will never be a version 2.0.</p></li>
</ol>
<blockquote>
<div><ol class="upperalpha simple">
<li><a class="reference external" href="https://semver.org/#spec-item-8">Major version must be incremented if any backwards incompatible changes are introduced to the public API.</a></li>
<li>We never implement any backwards incompatible changes, so…</li>
<li>We could see e.g. Thun version 1.273.3!</li>
<li><p><a class="reference external" href="https://semver.org/#spec-item-8">Major version must be incremented if any backwards incompatible changes are introduced to the public API.</a></p></li>
<li><p>We never implement any backwards incompatible changes, so…</p></li>
<li><p>We could see e.g. Thun version 1.273.3!</p></li>
</ol>
</div></blockquote>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
@ -73,25 +115,24 @@
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/NoUpdates.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -102,7 +143,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Quadratic formula &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script defer="defer" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Replacing Functions in the Dictionary" href="Replacing.html" />
@ -30,12 +30,14 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<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">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>from notebook_preamble import J, V, define
</pre></div>
</div>
<div class="section" id="quadratic-formula">
<section id="quadratic-formula">
<h1><a class="reference external" href="https://en.wikipedia.org/wiki/Quadratic_formula">Quadratic formula</a><a class="headerlink" href="#quadratic-formula" title="Permalink to this headline"></a></h1>
<p>Cf.
<a class="reference external" href="http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html">jp-quadratic.html</a></p>
@ -45,47 +47,47 @@
</pre></div>
</div>
<p><span class="math notranslate nohighlight">\(\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\)</span></p>
<div class="section" id="write-a-straightforward-program-with-variable-names">
<section id="write-a-straightforward-program-with-variable-names">
<h2>Write a straightforward program with variable names.<a class="headerlink" href="#write-a-straightforward-program-with-variable-names" title="Permalink to this headline"></a></h2>
<p>This math translates to Joy code in a straightforward manner. We are
going to use named variables to keep track of the arguments, then write
a definition without them.</p>
<div class="section" id="b">
<section id="b">
<h3><code class="docutils literal notranslate"><span class="pre">-b</span></code><a class="headerlink" href="#b" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="n">neg</span>
</pre></div>
</div>
</div>
<div class="section" id="sqrt-b-2-4-a-c">
</section>
<section id="sqrt-b-2-4-a-c">
<h3><code class="docutils literal notranslate"><span class="pre">sqrt(b^2</span> <span class="pre">-</span> <span class="pre">4</span> <span class="pre">*</span> <span class="pre">a</span> <span class="pre">*</span> <span class="pre">c)</span></code><a class="headerlink" href="#sqrt-b-2-4-a-c" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="n">sqr</span> <span class="mi">4</span> <span class="n">a</span> <span class="n">c</span> <span class="o">*</span> <span class="o">*</span> <span class="o">-</span> <span class="n">sqrt</span>
</pre></div>
</div>
</div>
<div class="section" id="a">
</section>
<section id="a">
<h3><code class="docutils literal notranslate"><span class="pre">/2a</span></code><a class="headerlink" href="#a" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="mi">2</span> <span class="o">*</span> <span class="o">/</span>
</pre></div>
</div>
</div>
<div class="section" id="id1">
</section>
<section id="id1">
<h3><code class="docutils literal notranslate"><span class="pre">±</span></code><a class="headerlink" href="#id1" title="Permalink to this headline"></a></h3>
<p>There is a function <code class="docutils literal notranslate"><span class="pre">pm</span></code> that accepts two values on the stack and
replaces them with their sum and difference.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pm</span> <span class="o">==</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="p">[</span><span class="o">-</span><span class="p">]</span> <span class="n">cleave</span> <span class="n">popdd</span>
</pre></div>
</div>
</div>
<div class="section" id="putting-them-together">
</section>
<section id="putting-them-together">
<h3>Putting Them Together<a class="headerlink" href="#putting-them-together" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="n">neg</span> <span class="n">b</span> <span class="n">sqr</span> <span class="mi">4</span> <span class="n">a</span> <span class="n">c</span> <span class="o">*</span> <span class="o">*</span> <span class="o">-</span> <span class="n">sqrt</span> <span class="n">pm</span> <span class="n">a</span> <span class="mi">2</span> <span class="o">*</span> <span class="p">[</span><span class="o">/</span><span class="p">]</span> <span class="n">cons</span> <span class="n">app2</span>
</pre></div>
</div>
<p>We use <code class="docutils literal notranslate"><span class="pre">app2</span></code> to compute both roots by using a quoted program
<code class="docutils literal notranslate"><span class="pre">[2a</span> <span class="pre">/]</span></code> built with <code class="docutils literal notranslate"><span class="pre">cons</span></code>.</p>
</div>
</div>
<div class="section" id="derive-a-definition">
</section>
</section>
<section id="derive-a-definition">
<h2>Derive a definition.<a class="headerlink" href="#derive-a-definition" title="Permalink to this headline"></a></h2>
<p>Working backwards we use <code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">dipd</span></code> to extract the code from
the variables:</p>
@ -98,11 +100,11 @@ the variables:</p>
</div>
<p>The three arguments are to the left, so we can “chop off” everything to
the right and say its the definition of the <code class="docutils literal notranslate"><span class="pre">quadratic</span></code> function:</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2&#39;)
</pre></div>
</div>
<p>Lets try it out:</p>
<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;3 1 1 quadratic&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;3 1 1 quadratic&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mf">0.3819660112501051</span> <span class="o">-</span><span class="mf">2.618033988749895</span>
@ -112,7 +114,7 @@ the right and say its the definition of the <code class="docutils literal not
lines are the <code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">dipd</span></code> combinators building the main program
by incorporating the values on the stack. Then that program runs and you
get the results. This is pretty typical of Joy code.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;-5 1 4 quadratic&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>V(&#39;-5 1 4 quadratic&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="o">-</span><span class="mi">5</span> <span class="mi">1</span> <span class="mi">4</span> <span class="n">quadratic</span>
@ -162,30 +164,55 @@ get the results. This is pretty typical of Joy code.</p>
<span class="mf">4.0</span> <span class="mf">1.0</span> <span class="o">.</span>
</pre></div>
</div>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Quadratic formula</a><ul>
<li><a class="reference internal" href="#write-a-straightforward-program-with-variable-names">Write a straightforward program with variable names.</a><ul>
<li><a class="reference internal" href="#b"><code class="docutils literal notranslate"><span class="pre">-b</span></code></a></li>
<li><a class="reference internal" href="#sqrt-b-2-4-a-c"><code class="docutils literal notranslate"><span class="pre">sqrt(b^2</span> <span class="pre">-</span> <span class="pre">4</span> <span class="pre">*</span> <span class="pre">a</span> <span class="pre">*</span> <span class="pre">c)</span></code></a></li>
<li><a class="reference internal" href="#a"><code class="docutils literal notranslate"><span class="pre">/2a</span></code></a></li>
<li><a class="reference internal" href="#id1"><code class="docutils literal notranslate"><span class="pre">±</span></code></a></li>
<li><a class="reference internal" href="#putting-them-together">Putting Them Together</a></li>
</ul>
</li>
<li><a class="reference internal" href="#derive-a-definition">Derive a definition.</a></li>
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -197,25 +224,24 @@ get the results. This is pretty typical of Joy code.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Quadratic.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -226,7 +252,7 @@ get the results. This is pretty typical of Joy code.</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Recursion Combinators &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Treating Trees I: Ordered Binary Trees" href="Ordered_Binary_Trees.html" />
@ -30,12 +29,14 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<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">DefinitionWrapper</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>from notebook_preamble import D, DefinitionWrapper, J, V, define
</pre></div>
</div>
<div class="section" id="recursion-combinators">
<section id="recursion-combinators">
<h1>Recursion Combinators<a class="headerlink" href="#recursion-combinators" title="Permalink to this headline"></a></h1>
<p>This article describes the <code class="docutils literal notranslate"><span class="pre">genrec</span></code> combinator, how to use it, and
several generic specializations.</p>
@ -46,7 +47,7 @@ several generic specializations.</p>
</div>
<p>From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun:</p>
<blockquote>
<div>“The genrec combinator takes four program parameters in addition to
<div><p>“The genrec combinator takes four program parameters in addition to
whatever data parameters it needs. Fourth from the top is an if-part,
followed by a then-part. If the if-part yields true, then the
then-part is executed and the combinator terminates. The other two
@ -55,8 +56,9 @@ false, the rec1-part is executed. Following that the four program
parameters and the combinator are again pushed onto the stack bundled
up in a quoted form. Then the rec2-part is executed, where it will
find the bundled form. Typically it will then execute the bundled
form, either with i or with app2, or some other combinator.”</div></blockquote>
<div class="section" id="designing-recursive-functions">
form, either with i or with app2, or some other combinator.”</p>
</div></blockquote>
<section id="designing-recursive-functions">
<h2>Designing Recursive Functions<a class="headerlink" href="#designing-recursive-functions" title="Permalink to this headline"></a></h2>
<p>The way to design one of these is to fix your base case and test and
then treat <code class="docutils literal notranslate"><span class="pre">R1</span></code> and <code class="docutils literal notranslate"><span class="pre">R2</span></code> as an else-part “sandwiching” a quotation
@ -73,8 +75,8 @@ from:</p>
</div>
<p>Set the stack arguments in front and figure out what <code class="docutils literal notranslate"><span class="pre">R1</span></code> and <code class="docutils literal notranslate"><span class="pre">R2</span></code>
have to do to apply the quoted <code class="docutils literal notranslate"><span class="pre">[F]</span></code> in the proper way.</p>
</div>
<div class="section" id="primitive-recursive-functions">
</section>
<section id="primitive-recursive-functions">
<h2>Primitive Recursive Functions<a class="headerlink" href="#primitive-recursive-functions" title="Permalink to this headline"></a></h2>
<p>Primitive recursive functions are those where <code class="docutils literal notranslate"><span class="pre">R2</span> <span class="pre">==</span> <span class="pre">i</span></code>.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">P</span> <span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R</span><span class="p">]</span> <span class="n">primrec</span>
@ -82,35 +84,35 @@ have to do to apply the quoted <code class="docutils literal notranslate"><span
<span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R</span> <span class="n">P</span><span class="p">]</span> <span class="n">ifte</span>
</pre></div>
</div>
</div>
<div class="section" id="hylomorphism">
</section>
<section id="hylomorphism">
<h2><a class="reference external" href="https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29">Hylomorphism</a><a class="headerlink" href="#hylomorphism" title="Permalink to this headline"></a></h2>
<p>A
<a class="reference external" href="https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29">hylomorphism</a>
is a recursive function <code class="docutils literal notranslate"><span class="pre">H</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">C</span></code> that converts a value of type
<code class="docutils literal notranslate"><span class="pre">A</span></code> into a value of type <code class="docutils literal notranslate"><span class="pre">C</span></code> by means of:</p>
<ul class="simple">
<li>A generator <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">(B,</span> <span class="pre">A)</span></code></li>
<li>A combiner <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">::</span> <span class="pre">(B,</span> <span class="pre">C)</span> <span class="pre">-&gt;</span> <span class="pre">C</span></code></li>
<li>A predicate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">Bool</span></code> to detect the base case</li>
<li>A base case value <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">::</span> <span class="pre">C</span></code></li>
<li>Recursive calls (zero or more); it has a “call stack in the form of a
cons list”.</li>
<li><p>A generator <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">(B,</span> <span class="pre">A)</span></code></p></li>
<li><p>A combiner <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">::</span> <span class="pre">(B,</span> <span class="pre">C)</span> <span class="pre">-&gt;</span> <span class="pre">C</span></code></p></li>
<li><p>A predicate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">Bool</span></code> to detect the base case</p></li>
<li><p>A base case value <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">::</span> <span class="pre">C</span></code></p></li>
<li><p>Recursive calls (zero or more); it has a “call stack in the form of a
cons list”.</p></li>
</ul>
<p>It may be helpful to see this function implemented in imperative Python
code.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hylomorphism</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Return a hylomorphism function H.&#39;&#39;&#39;</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>def hylomorphism(c, F, P, G):
&#39;&#39;&#39;Return a hylomorphism function H.&#39;&#39;&#39;
<span class="k">def</span> <span class="nf">H</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
<span class="k">if</span> <span class="n">P</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">c</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">b</span><span class="p">,</span> <span class="n">aa</span> <span class="o">=</span> <span class="n">G</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">F</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">H</span><span class="p">(</span><span class="n">aa</span><span class="p">))</span> <span class="c1"># b is stored in the stack frame during recursive call to H().</span>
<span class="k">return</span> <span class="n">result</span>
def H(a):
if P(a):
result = c
else:
b, aa = G(a)
result = F(b, H(aa)) # b is stored in the stack frame during recursive call to H().
return result
<span class="k">return</span> <span class="n">H</span>
return H
</pre></div>
</div>
<p>Cf. <a class="reference external" href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125">“Bananas, Lenses, &amp; Barbed
@ -118,8 +120,8 @@ Wire”</a></p>
<p>Note that during evaluation of <code class="docutils literal notranslate"><span class="pre">H()</span></code> the intermediate <code class="docutils literal notranslate"><span class="pre">b</span></code> values are
stored in the Python call stack. This is what is meant by “call stack in
the form of a cons list”.</p>
</div>
<div class="section" id="hylomorphism-in-joy">
</section>
<section id="hylomorphism-in-joy">
<h2>Hylomorphism in Joy<a class="headerlink" href="#hylomorphism-in-joy" title="Permalink to this headline"></a></h2>
<p>We can define a combinator <code class="docutils literal notranslate"><span class="pre">hylomorphism</span></code> that will make a
hylomorphism combinator <code class="docutils literal notranslate"><span class="pre">H</span></code> from constituent parts.</p>
@ -155,8 +157,8 @@ it is a simple specialization of the general recursion combinator.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">c</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">hylomorphism</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="n">c</span><span class="p">]</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">F</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
</div>
<div class="section" id="derivation-of-hylomorphism-combinator">
</section>
<section id="derivation-of-hylomorphism-combinator">
<h2>Derivation of <code class="docutils literal notranslate"><span class="pre">hylomorphism</span></code> combinator<a class="headerlink" href="#derivation-of-hylomorphism-combinator" title="Permalink to this headline"></a></h2>
<p>Now we just need to derive a definition that builds the <code class="docutils literal notranslate"><span class="pre">genrec</span></code>
arguments out of the pieces given to the <code class="docutils literal notranslate"><span class="pre">hylomorphism</span></code> combinator.</p>
@ -167,9 +169,9 @@ arguments out of the pieces given to the <code class="docutils literal notransla
</div>
<p>Working in reverse:</p>
<ul class="simple">
<li>Use <code class="docutils literal notranslate"><span class="pre">swoncat</span></code> twice to decouple <code class="docutils literal notranslate"><span class="pre">[c]</span></code> and <code class="docutils literal notranslate"><span class="pre">[F]</span></code>.</li>
<li>Use <code class="docutils literal notranslate"><span class="pre">unit</span></code> to dequote <code class="docutils literal notranslate"><span class="pre">c</span></code>.</li>
<li>Use <code class="docutils literal notranslate"><span class="pre">dipd</span></code> to untangle <code class="docutils literal notranslate"><span class="pre">[unit</span> <span class="pre">[pop]</span> <span class="pre">swoncat]</span></code> from the givens.</li>
<li><p>Use <code class="docutils literal notranslate"><span class="pre">swoncat</span></code> twice to decouple <code class="docutils literal notranslate"><span class="pre">[c]</span></code> and <code class="docutils literal notranslate"><span class="pre">[F]</span></code>.</p></li>
<li><p>Use <code class="docutils literal notranslate"><span class="pre">unit</span></code> to dequote <code class="docutils literal notranslate"><span class="pre">c</span></code>.</p></li>
<li><p>Use <code class="docutils literal notranslate"><span class="pre">dipd</span></code> to untangle <code class="docutils literal notranslate"><span class="pre">[unit</span> <span class="pre">[pop]</span> <span class="pre">swoncat]</span></code> from the givens.</p></li>
</ul>
<p>So:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="n">c</span><span class="p">]</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">F</span><span class="p">]</span> <span class="n">genrec</span>
@ -183,40 +185,40 @@ the left so we have a definition for <code class="docutils literal notranslate">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">hylomorphism</span> <span class="o">==</span> <span class="p">[</span><span class="n">unit</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="n">swoncat</span><span class="p">]</span> <span class="n">dipd</span> <span class="p">[</span><span class="n">dip</span><span class="p">]</span> <span class="n">swoncat</span> <span class="n">genrec</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec&#39;)
</pre></div>
</div>
<div class="section" id="example-finding-triangular-numbers">
<section id="example-finding-triangular-numbers">
<h3>Example: Finding <a class="reference external" href="https://en.wikipedia.org/wiki/Triangular_number">Triangular Numbers</a><a class="headerlink" href="#example-finding-triangular-numbers" title="Permalink to this headline"></a></h3>
<p>Lets write a function that, given a positive integer, returns the sum
of all positive integers less than that one. (In this case the types
<code class="docutils literal notranslate"><span class="pre">A</span></code>, <code class="docutils literal notranslate"><span class="pre">B</span></code> and <code class="docutils literal notranslate"><span class="pre">C</span></code> are all <code class="docutils literal notranslate"><span class="pre">int</span></code>.)</p>
<p>To sum a range of integers from 0 to <em>n</em> - 1:</p>
<ul class="simple">
<li><code class="docutils literal notranslate"><span class="pre">[P]</span></code> is <code class="docutils literal notranslate"><span class="pre">[1</span> <span class="pre">&lt;=]</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">c</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">[G]</span></code> is <code class="docutils literal notranslate"><span class="pre">[--</span> <span class="pre">dup]</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">[F]</span></code> is <code class="docutils literal notranslate"><span class="pre">[+]</span></code></li>
<li><p><code class="docutils literal notranslate"><span class="pre">[P]</span></code> is <code class="docutils literal notranslate"><span class="pre">[1</span> <span class="pre">&lt;=]</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">c</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">[G]</span></code> is <code class="docutils literal notranslate"><span class="pre">[--</span> <span class="pre">dup]</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">[F]</span></code> is <code class="docutils literal notranslate"><span class="pre">[+]</span></code></p></li>
</ul>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;triangular_number == [1 &lt;=] 0 [-- dup] [+] hylomorphism&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;triangular_number == [1 &lt;=] 0 [-- dup] [+] hylomorphism&#39;)
</pre></div>
</div>
<p>Lets try it:</p>
<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;5 triangular_number&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;5 triangular_number&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span>
</pre></div>
</div>
<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;[0 1 2 3 4 5 6] [triangular_number] map&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[0 1 2 3 4 5 6] [triangular_number] map&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">6</span> <span class="mi">10</span> <span class="mi">15</span><span class="p">]</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="four-specializations">
</section>
</section>
<section id="four-specializations">
<h2>Four Specializations<a class="headerlink" href="#four-specializations" title="Permalink to this headline"></a></h2>
<p>There are at least four kinds of recursive combinator, depending on two
choices. The first choice is whether the combiner function <code class="docutils literal notranslate"><span class="pre">F</span></code> should
@ -244,7 +246,7 @@ Consider the recursive branches:</p>
</div>
<p>The following four sections illustrate how these work, omitting the
predicate evaluation.</p>
<div class="section" id="h1">
<section id="h1">
<h3><code class="docutils literal notranslate"><span class="pre">H1</span></code><a class="headerlink" href="#h1" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H1</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="n">c</span><span class="p">]</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">F</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
@ -271,8 +273,8 @@ the intermediate results along with the pending combiner functions. When
the base case is reached the last term is replaced by the identity value
<code class="docutils literal notranslate"><span class="pre">c</span></code> and the continuation “collapses” into the final result using the
combiner <code class="docutils literal notranslate"><span class="pre">F</span></code>.</p>
</div>
<div class="section" id="h2">
</section>
<section id="h2">
<h3><code class="docutils literal notranslate"><span class="pre">H2</span></code><a class="headerlink" href="#h2" title="Permalink to this headline"></a></h3>
<p>When you can start with the identity value <code class="docutils literal notranslate"><span class="pre">c</span></code> on the stack and the
combiner <code class="docutils literal notranslate"><span class="pre">F</span></code> can operate as you go using the intermediate results
@ -297,8 +299,8 @@ reverse order.</p>
... d″
</pre></div>
</div>
</div>
<div class="section" id="h3">
</section>
<section id="h3">
<h3><code class="docutils literal notranslate"><span class="pre">H3</span></code><a class="headerlink" href="#h3" title="Permalink to this headline"></a></h3>
<p>If you examine the traces above youll see that the combiner <code class="docutils literal notranslate"><span class="pre">F</span></code> only
gets to operate on the results of <code class="docutils literal notranslate"><span class="pre">G</span></code>, it never “sees” the first value
@ -326,8 +328,8 @@ one item instead of two (the b is instead the duplicate of a.)</p>
... d″
</pre></div>
</div>
</div>
<div class="section" id="h4">
</section>
<section id="h4">
<h3><code class="docutils literal notranslate"><span class="pre">H4</span></code><a class="headerlink" href="#h4" title="Permalink to this headline"></a></h3>
<p>And, last but not least, if you can combine as you go, starting with
<code class="docutils literal notranslate"><span class="pre">c</span></code>, and the combiner <code class="docutils literal notranslate"><span class="pre">F</span></code> needs to work on the current item, this is
@ -350,9 +352,9 @@ the form:</p>
... d″
</pre></div>
</div>
</div>
</div>
<div class="section" id="anamorphism">
</section>
</section>
<section id="anamorphism">
<h2>Anamorphism<a class="headerlink" href="#anamorphism" title="Permalink to this headline"></a></h2>
<p>An anamorphism can be defined as a hylomorphism that uses <code class="docutils literal notranslate"><span class="pre">[]</span></code> for
<code class="docutils literal notranslate"><span class="pre">c</span></code> and <code class="docutils literal notranslate"><span class="pre">swons</span></code> for <code class="docutils literal notranslate"><span class="pre">F</span></code>. An anamorphic function builds a list of
@ -360,68 +362,68 @@ values.</p>
<div class="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">P</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
<div class="section" id="range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n">
<h3><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al.&nbsp;An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.<a class="headerlink" href="#range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n" title="Permalink to this headline"></a></h3>
<section id="range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n">
<h3><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al. An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.<a class="headerlink" href="#range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n" title="Permalink to this headline"></a></h3>
<p>Each of the above variations can be used to make four slightly different
<code class="docutils literal notranslate"><span class="pre">range</span></code> functions.</p>
<div class="section" id="range-with-h1">
<section id="range-with-h1">
<h4><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H1</span></code><a class="headerlink" href="#range-with-h1" title="Permalink to this headline"></a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H1</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="n">c</span><span class="p">]</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">F</span><span class="p">]</span> <span class="n">genrec</span>
<span class="o">==</span> <span class="p">[</span><span class="mi">0</span> <span class="o">&lt;=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;range == [0 &lt;=] [] [-- dup] [swons] hylomorphism&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;range == [0 &lt;=] [] [-- dup] [swons] hylomorphism&#39;)
</pre></div>
</div>
<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;5 range&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;5 range&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="range-with-h2">
</section>
<section id="range-with-h2">
<h4><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H2</span></code><a class="headerlink" href="#range-with-h2" title="Permalink to this headline"></a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H2</span> <span class="o">==</span> <span class="n">c</span> <span class="n">swap</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[</span><span class="n">G</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">primrec</span>
<span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="mi">0</span> <span class="o">&lt;=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">primrec</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;range_reverse == [] swap [0 &lt;=] [pop] [-- dup [swons] dip] primrec&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;range_reverse == [] swap [0 &lt;=] [pop] [-- dup [swons] dip] primrec&#39;)
</pre></div>
</div>
<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;5 range_reverse&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;5 range_reverse&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="range-with-h3">
</section>
<section id="range-with-h3">
<h4><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H3</span></code><a class="headerlink" href="#range-with-h3" title="Permalink to this headline"></a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H3</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="n">c</span><span class="p">]</span> <span class="p">[[</span><span class="n">G</span><span class="p">]</span> <span class="n">dupdip</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">F</span><span class="p">]</span> <span class="n">genrec</span>
<span class="o">==</span> <span class="p">[</span><span class="mi">0</span> <span class="o">&lt;=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[[</span><span class="o">--</span><span class="p">]</span> <span class="n">dupdip</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;ranger == [0 &lt;=] [pop []] [[--] dupdip] [dip swons] genrec&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;ranger == [0 &lt;=] [pop []] [[--] dupdip] [dip swons] genrec&#39;)
</pre></div>
</div>
<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;5 ranger&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;5 ranger&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">5</span> <span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="range-with-h4">
</section>
<section id="range-with-h4">
<h4><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H4</span></code><a class="headerlink" href="#range-with-h4" title="Permalink to this headline"></a></h4>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H4</span> <span class="o">==</span> <span class="n">c</span> <span class="n">swap</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[[</span><span class="n">F</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">G</span> <span class="p">]</span> <span class="n">primrec</span>
<span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="mi">0</span> <span class="o">&lt;=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dupdip</span> <span class="o">--</span><span class="p">]</span> <span class="n">primrec</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;ranger_reverse == [] swap [0 &lt;=] [pop] [[swons] dupdip --] primrec&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;ranger_reverse == [] swap [0 &lt;=] [pop] [[swons] dupdip --] primrec&#39;)
</pre></div>
</div>
<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;5 ranger_reverse&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;5 ranger_reverse&#39;)
</pre></div>
</div>
<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">4</span> <span class="mi">5</span><span class="p">]</span>
@ -430,10 +432,10 @@ values.</p>
<p>Hopefully this illustrates the workings of the variations. For more
insight you can run the cells using the <code class="docutils literal notranslate"><span class="pre">V()</span></code> function instead of the
<code class="docutils literal notranslate"><span class="pre">J()</span></code> function to get a trace of the Joy evaluation.</p>
</div>
</div>
</div>
<div class="section" id="catamorphism">
</section>
</section>
</section>
<section id="catamorphism">
<h2>Catamorphism<a class="headerlink" href="#catamorphism" title="Permalink to this headline"></a></h2>
<p>A catamorphism can be defined as a hylomorphism that uses
<code class="docutils literal notranslate"><span class="pre">[uncons</span> <span class="pre">swap]</span></code> for <code class="docutils literal notranslate"><span class="pre">[G]</span></code> and <code class="docutils literal notranslate"><span class="pre">[[]</span> <span class="pre">=]</span></code> (or just <code class="docutils literal notranslate"><span class="pre">[not]</span></code>) for the
@ -442,27 +444,27 @@ and makes some new value.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="n">c</span> <span class="p">[</span><span class="n">uncons</span> <span class="n">swap</span><span class="p">]</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;swuncons == uncons swap&#39;</span><span class="p">)</span> <span class="c1"># Awkward name.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;swuncons == uncons swap&#39;) # Awkward name.
</pre></div>
</div>
<p>An example of a catamorphism is the sum function.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">sum</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="mi">0</span> <span class="p">[</span><span class="n">swuncons</span><span class="p">]</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;sum == [not] 0 [swuncons] [+] hylomorphism&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;sum == [not] 0 [swuncons] [+] hylomorphism&#39;)
</pre></div>
</div>
<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;[5 4 3 2 1] sum&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[5 4 3 2 1] sum&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
</pre></div>
</div>
<div class="section" id="the-step-combinator">
<section id="the-step-combinator">
<h3>The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator<a class="headerlink" href="#the-step-combinator" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator will usually be better to use than
<code class="docutils literal notranslate"><span class="pre">catamorphism</span></code>.</p>
<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;[step] help&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[step] help&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Run</span> <span class="n">a</span> <span class="n">quoted</span> <span class="n">program</span> <span class="n">on</span> <span class="n">each</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">a</span> <span class="n">sequence</span><span class="o">.</span>
@ -486,18 +488,18 @@ and makes some new value.</p>
<span class="n">on</span> <span class="n">top</span> <span class="n">of</span> <span class="n">the</span> <span class="n">stack</span><span class="o">.</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;sum == 0 swap [+] step&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;sum == 0 swap [+] step&#39;)
</pre></div>
</div>
<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;[5 4 3 2 1] sum&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[5 4 3 2 1] sum&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="example-factorial-function">
</section>
</section>
<section id="example-factorial-function">
<h2>Example: Factorial Function<a class="headerlink" href="#example-factorial-function" title="Permalink to this headline"></a></h2>
<p>For the Factorial function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H4</span> <span class="o">==</span> <span class="n">c</span> <span class="n">swap</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[[</span><span class="n">F</span><span class="p">]</span> <span class="n">dupdip</span> <span class="n">G</span><span class="p">]</span> <span class="n">primrec</span>
@ -510,17 +512,17 @@ and makes some new value.</p>
<span class="n">P</span> <span class="o">==</span> <span class="mi">1</span> <span class="o">&lt;=</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;factorial == 1 swap [1 &lt;=] [pop] [[*] dupdip --] primrec&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;factorial == 1 swap [1 &lt;=] [pop] [[*] dupdip --] primrec&#39;)
</pre></div>
</div>
<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;5 factorial&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;5 factorial&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">120</span>
</pre></div>
</div>
</div>
<div class="section" id="example-tails">
</section>
<section id="example-tails">
<h2>Example: <code class="docutils literal notranslate"><span class="pre">tails</span></code><a class="headerlink" href="#example-tails" title="Permalink to this headline"></a></h2>
<p>An example of a paramorphism for lists given in the <a class="reference external" href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125">“Bananas…”
paper</a>
@ -542,37 +544,37 @@ pattern <code class="docutils literal notranslate"><span class="pre">H2</span></
<span class="n">P</span> <span class="o">==</span> <span class="ow">not</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;tails == [] swap [not] [pop] [rest dup [swons] dip] primrec&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;tails == [] swap [not] [pop] [rest dup [swons] dip] primrec&#39;)
</pre></div>
</div>
<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;[1 2 3] tails&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1 2 3] tails&#39;)
</pre></div>
</div>
<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="p">[</span><span class="mi">2</span> <span class="mi">3</span><span class="p">]]</span>
</pre></div>
</div>
</div>
<div class="section" id="conclusion-patterns-of-recursion">
</section>
<section id="conclusion-patterns-of-recursion">
<h2>Conclusion: Patterns of Recursion<a class="headerlink" href="#conclusion-patterns-of-recursion" title="Permalink to this headline"></a></h2>
<p>Our story so far…</p>
<div class="section" id="hylo-ana-cata">
<section id="hylo-ana-cata">
<h3>Hylo-, Ana-, Cata-<a class="headerlink" href="#hylo-ana-cata" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span> <span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="n">c</span> <span class="p">]</span> <span class="p">[</span><span class="n">G</span> <span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">F</span> <span class="p">]</span> <span class="n">genrec</span>
<span class="n">A</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span> <span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[</span><span class="n">G</span> <span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swap</span> <span class="n">cons</span><span class="p">]</span> <span class="n">genrec</span>
<span class="n">C</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="n">c</span> <span class="p">]</span> <span class="p">[</span><span class="n">uncons</span> <span class="n">swap</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">F</span> <span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
</div>
<div class="section" id="para">
</section>
<section id="para">
<h3>Para-, ?-, ?-<a class="headerlink" href="#para" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>P == c swap [P ] [pop] [[F ] dupdip G ] primrec
? == [] swap [P ] [pop] [[swap cons] dupdip G ] primrec
? == c swap [not] [pop] [[F ] dupdip uncons swap] primrec
</pre></div>
</div>
</div>
</div>
<div class="section" id="appendix-fun-with-symbols">
</section>
</section>
<section id="appendix-fun-with-symbols">
<h2>Appendix: Fun with Symbols<a class="headerlink" href="#appendix-fun-with-symbols" title="Permalink to this headline"></a></h2>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>|[ (c, F), (G, P) ]| == (|c, F|) • [(G, P)]
</pre></div>
@ -584,58 +586,55 @@ Wire”</a></p>
</div>
<p>I think they are having slightly too much fun with the symbols. However,
“Too much is always better than not enough.”</p>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Recursion Combinators</a><ul>
<li><a class="reference internal" href="#designing-recursive-functions">Designing Recursive Functions</a></li>
<li><a class="reference internal" href="#primitive-recursive-functions">Primitive Recursive Functions</a></li>
<li><a class="reference internal" href="#hylomorphism">Hylomorphism</a></li>
<li><a class="reference internal" href="#hylomorphism-in-joy">Hylomorphism in Joy</a></li>
<li><a class="reference internal" href="#derivation-of-hylomorphism-combinator">Derivation of <code class="docutils literal notranslate"><span class="pre">hylomorphism</span></code> combinator</a><ul>
<li><a class="reference internal" href="#example-finding-triangular-numbers">Example: Finding Triangular Numbers</a></li>
</ul>
</li>
<li><a class="reference internal" href="#four-specializations">Four Specializations</a><ul>
<li><a class="reference internal" href="#h1"><code class="docutils literal notranslate"><span class="pre">H1</span></code></a></li>
<li><a class="reference internal" href="#h2"><code class="docutils literal notranslate"><span class="pre">H2</span></code></a></li>
<li><a class="reference internal" href="#h3"><code class="docutils literal notranslate"><span class="pre">H3</span></code></a></li>
<li><a class="reference internal" href="#h4"><code class="docutils literal notranslate"><span class="pre">H4</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#anamorphism">Anamorphism</a><ul>
<li><a class="reference internal" href="#range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n"><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al.&nbsp;An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</a><ul>
<li><a class="reference internal" href="#range-with-h1"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H1</span></code></a></li>
<li><a class="reference internal" href="#range-with-h2"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H2</span></code></a></li>
<li><a class="reference internal" href="#range-with-h3"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H3</span></code></a></li>
<li><a class="reference internal" href="#range-with-h4"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H4</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#catamorphism">Catamorphism</a><ul>
<li><a class="reference internal" href="#the-step-combinator">The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator</a></li>
</ul>
</li>
<li><a class="reference internal" href="#example-factorial-function">Example: Factorial Function</a></li>
<li><a class="reference internal" href="#example-tails">Example: <code class="docutils literal notranslate"><span class="pre">tails</span></code></a></li>
<li><a class="reference internal" href="#conclusion-patterns-of-recursion">Conclusion: Patterns of Recursion</a><ul>
<li><a class="reference internal" href="#hylo-ana-cata">Hylo-, Ana-, Cata-</a></li>
<li><a class="reference internal" href="#para">Para-, ?-, ?-</a></li>
</ul>
</li>
<li><a class="reference internal" href="#appendix-fun-with-symbols">Appendix: Fun with Symbols</a></li>
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -647,25 +646,24 @@ Wire”</a></p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Recursion_Combinators.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -676,7 +674,7 @@ Wire”</a></p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Replacing Functions in the Dictionary &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Recursion Combinators" href="Recursion_Combinators.html" />
@ -30,23 +29,25 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="replacing-functions-in-the-dictionary">
<section id="replacing-functions-in-the-dictionary">
<h1>Replacing Functions in the Dictionary<a class="headerlink" href="#replacing-functions-in-the-dictionary" title="Permalink to this headline"></a></h1>
<p>For now, there is no way to define new functions from within the Joy
language. All functions (and the interpreter) all accept and return a
dictionary parameter (in addition to the stack and expression) so that
we can implement e.g.&nbsp;a function that adds new functions to the
we can implement e.g. a function that adds new functions to the
dictionary. However, theres no function that does that. Adding a new
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.</p>
<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>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>from notebook_preamble import D, J, V
</pre></div>
</div>
<div class="section" id="a-long-trace">
<section id="a-long-trace">
<h2>A long trace<a class="headerlink" href="#a-long-trace" title="Permalink to this headline"></a></h2>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;[23 18] average&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>V(&#39;[23 18] average&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">23</span> <span class="mi">18</span><span class="p">]</span> <span class="n">average</span>
@ -93,8 +94,8 @@ it in Python, not Joy.</p>
<span class="mf">20.5</span> <span class="o">.</span>
</pre></div>
</div>
</div>
<div class="section" id="replacing-size-with-a-python-version">
</section>
<section id="replacing-size-with-a-python-version">
<h2>Replacing <code class="docutils literal notranslate"><span class="pre">size</span></code> with a Python version<a class="headerlink" href="#replacing-size-with-a-python-version" title="Permalink to this headline"></a></h2>
<p>Both <code class="docutils literal notranslate"><span class="pre">sum</span></code> and <code class="docutils literal notranslate"><span class="pre">size</span></code> each convert a sequence to a single value.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="nb">sum</span> <span class="o">==</span> <span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="n">step</span>
@ -104,30 +105,30 @@ it in Python, not Joy.</p>
<p>An efficient <code class="docutils literal notranslate"><span class="pre">sum</span></code> function is already in the library. But for
<code class="docutils literal notranslate"><span class="pre">size</span></code> we can use a “compiled” version hand-written in Python to speed
up evaluation and make the trace more readable.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.library</span> <span class="k">import</span> <span class="n">SimpleFunctionWrapper</span>
<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="k">import</span> <span class="n">iter_stack</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>from joy.library import SimpleFunctionWrapper
from joy.utils.stack import iter_stack
<span class="nd">@SimpleFunctionWrapper</span>
<span class="k">def</span> <span class="nf">size</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="sd">&#39;&#39;&#39;Return the size of the sequence on the stack.&#39;&#39;&#39;</span>
<span class="n">sequence</span><span class="p">,</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">stack</span>
<span class="n">n</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="n">iter_stack</span><span class="p">(</span><span class="n">sequence</span><span class="p">):</span>
<span class="n">n</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="n">n</span><span class="p">,</span> <span class="n">stack</span>
@SimpleFunctionWrapper
def size(stack):
&#39;&#39;&#39;Return the size of the sequence on the stack.&#39;&#39;&#39;
sequence, stack = stack
n = 0
for _ in iter_stack(sequence):
n += 1
return n, stack
</pre></div>
</div>
<p>Now we replace the old version in the dictionary with the new version,
and re-evaluate the expression.</p>
<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;size&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">size</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>D[&#39;size&#39;] = size
</pre></div>
</div>
</div>
<div class="section" id="a-shorter-trace">
</section>
<section id="a-shorter-trace">
<h2>A shorter trace<a class="headerlink" href="#a-shorter-trace" title="Permalink to this headline"></a></h2>
<p>You can see that <code class="docutils literal notranslate"><span class="pre">size</span></code> now executes in a single step.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;[23 18] average&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>V(&#39;[23 18] average&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">23</span> <span class="mi">18</span><span class="p">]</span> <span class="n">average</span>
@ -161,24 +162,55 @@ and re-evaluate the expression.</p>
<span class="mf">20.5</span> <span class="o">.</span>
</pre></div>
</div>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Replacing Functions in the Dictionary</a><ul>
<li><a class="reference internal" href="#a-long-trace">A long trace</a></li>
<li><a class="reference internal" href="#replacing-size-with-a-python-version">Replacing <code class="docutils literal notranslate"><span class="pre">size</span></code> with a Python version</a></li>
<li><a class="reference internal" href="#a-shorter-trace">A shorter trace</a></li>
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -190,25 +222,24 @@ and re-evaluate the expression.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Replacing.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -219,7 +250,7 @@ and re-evaluate the expression.</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>The Four Fundamental Operations of Definite Action &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="∂RE" href="Derivatives_of_Regular_Expressions.html" />
@ -30,19 +29,21 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="the-four-fundamental-operations-of-definite-action">
<section id="the-four-fundamental-operations-of-definite-action">
<h1>The Four Fundamental Operations of Definite Action<a class="headerlink" href="#the-four-fundamental-operations-of-definite-action" title="Permalink to this headline"></a></h1>
<p>All definite actions (computer program) can be defined by four
fundamental patterns of combination:</p>
<ol class="arabic simple">
<li>Sequence</li>
<li>Branch</li>
<li>Loop</li>
<li>Parallel</li>
<li><p>Sequence</p></li>
<li><p>Branch</p></li>
<li><p>Loop</p></li>
<li><p>Parallel</p></li>
</ol>
<div class="section" id="sequence">
<section id="sequence">
<h2>Sequence<a class="headerlink" href="#sequence" title="Permalink to this headline"></a></h2>
<p>Do one thing after another. In joy this is represented by putting two
symbols together, juxtaposition:</p>
@ -51,8 +52,8 @@ symbols together, juxtaposition:</p>
</div>
<p>Operations have inputs and outputs. The outputs of <code class="docutils literal notranslate"><span class="pre">foo</span></code> must be
compatible in “arity”, type, and shape with the inputs of <code class="docutils literal notranslate"><span class="pre">bar</span></code>.</p>
</div>
<div class="section" id="branch">
</section>
<section id="branch">
<h2>Branch<a class="headerlink" href="#branch" title="Permalink to this headline"></a></h2>
<p>Do one thing or another.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">boolean</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="n">branch</span>
@ -93,7 +94,7 @@ outputs for <code class="docutils literal notranslate"><span class="pre">foo</sp
<span class="n">foo</span> <span class="n">T</span> <span class="n">bar</span>
</pre></div>
</div>
<div class="section" id="ifte">
<section id="ifte">
<h3><code class="docutils literal notranslate"><span class="pre">ifte</span></code><a class="headerlink" href="#ifte" title="Permalink to this headline"></a></h3>
<p>Often it will be easier on the programmer to write branching code with
the predicate specified in a quote. The <code class="docutils literal notranslate"><span class="pre">ifte</span></code> combinator provides
@ -115,9 +116,9 @@ evaluate it. I reflect this in the structure of the stack effect comment
of <code class="docutils literal notranslate"><span class="pre">branch</span></code>, it will only accept Boolean values, and in the definition
of <code class="docutils literal notranslate"><span class="pre">ifte</span></code> above by including <code class="docutils literal notranslate"><span class="pre">not</span></code> in the quote, which also has the
effect that the subject quotes are in the proper order for <code class="docutils literal notranslate"><span class="pre">branch</span></code>.)</p>
</div>
</div>
<div class="section" id="loop">
</section>
</section>
<section id="loop">
<h2>Loop<a class="headerlink" href="#loop" title="Permalink to this headline"></a></h2>
<p>Do one thing zero or more times.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">boolean</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
@ -168,7 +169,7 @@ boolean flag for the next iteration:</p>
<span class="n">G</span> <span class="n">G</span> <span class="n">G</span>
</pre></div>
</div>
<div class="section" id="while">
<section id="while">
<h3><code class="docutils literal notranslate"><span class="pre">while</span></code><a class="headerlink" href="#while" title="Permalink to this headline"></a></h3>
<p>Keep doing <code class="docutils literal notranslate"><span class="pre">B</span></code> <em>while</em> some predicate <code class="docutils literal notranslate"><span class="pre">P</span></code> is true. This is
convenient as the predicate function is made nullary automatically and
@ -191,9 +192,9 @@ flag for the next iteration:</p>
<span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span> <span class="p">[</span><span class="n">B</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">nullary</span><span class="p">]</span> <span class="n">loop</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="parallel">
</section>
</section>
<section id="parallel">
<h2>Parallel<a class="headerlink" href="#parallel" title="Permalink to this headline"></a></h2>
<p>The <em>parallel</em> operation indicates that two (or more) functions <em>do not
interfere</em> with each other and so can run in parallel. The main
@ -201,10 +202,10 @@ difficulty in this sort of thing is orchestrating the recombining
(“join” or “wait”) of the results of the functions after they finish.</p>
<p>The current implementaions and the following definitions <em>are not
actually parallel</em> (yet), but there is no reason they couldnt be
reimplemented in terms of e.g.&nbsp;Python threads. I am not concerned with
reimplemented in terms of e.g. Python threads. I am not concerned with
performance of the system just yet, only the elegance of the code it
allows us to write.</p>
<div class="section" id="cleave">
<section id="cleave">
<h3><code class="docutils literal notranslate"><span class="pre">cleave</span></code><a class="headerlink" href="#cleave" title="Permalink to this headline"></a></h3>
<p>Joy has a few parallel combinators, the main one being <code class="docutils literal notranslate"><span class="pre">cleave</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="n">x</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">cleave</span>
@ -225,8 +226,8 @@ Elliotts “Compiling to Categories” paper, et. al.)</p>
<p>Just a thought, if you <code class="docutils literal notranslate"><span class="pre">cleave</span></code> two jobs and one requires more time to
finish than the other youd like to be able to assign resources
accordingly so that they both finish at the same time.</p>
</div>
<div class="section" id="apply-functions">
</section>
<section id="apply-functions">
<h3>“Apply” Functions<a class="headerlink" href="#apply-functions" title="Permalink to this headline"></a></h3>
<p>There are also <code class="docutils literal notranslate"><span class="pre">app2</span></code> and <code class="docutils literal notranslate"><span class="pre">app3</span></code> which run a single quote on more
than one value:</p>
@ -257,8 +258,8 @@ value.)</p>
<span class="n">a</span> <span class="n">b</span>
</pre></div>
</div>
</div>
<div class="section" id="map">
</section>
<section id="map">
<h3><code class="docutils literal notranslate"><span class="pre">map</span></code><a class="headerlink" href="#map" title="Permalink to this headline"></a></h3>
<p>The common <code class="docutils literal notranslate"><span class="pre">map</span></code> function in Joy should also be though of as a
<em>parallel</em> operator:</p>
@ -266,9 +267,9 @@ value.)</p>
</pre></div>
</div>
<p>There is no reason why the implementation of <code class="docutils literal notranslate"><span class="pre">map</span></code> couldnt distribute
the <code class="docutils literal notranslate"><span class="pre">Q</span></code> function over e.g.&nbsp;a pool of worker CPUs.</p>
</div>
<div class="section" id="pam">
the <code class="docutils literal notranslate"><span class="pre">Q</span></code> function over e.g. a pool of worker CPUs.</p>
</section>
<section id="pam">
<h3><code class="docutils literal notranslate"><span class="pre">pam</span></code><a class="headerlink" href="#pam" title="Permalink to this headline"></a></h3>
<p>One of my favorite combinators, the <code class="docutils literal notranslate"><span class="pre">pam</span></code> combinator is just:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pam</span> <span class="o">==</span> <span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="nb">map</span>
@ -281,21 +282,21 @@ stack and combine their (first) outputs in a result list.</p>
<span class="p">[</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">...</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="handling-other-kinds-of-join">
</section>
<section id="handling-other-kinds-of-join">
<h3>Handling Other Kinds of Join<a class="headerlink" href="#handling-other-kinds-of-join" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">cleave</span></code> operators and others all have pretty brutal join
semantics: everything works and we always wait for every
sub-computation. We can imagine a few different potentially useful
patterns of “joining” results from parallel combinators.</p>
<div class="section" id="first-to-finish">
<section id="first-to-finish">
<h4>first-to-finish<a class="headerlink" href="#first-to-finish" title="Permalink to this headline"></a></h4>
<p>Thinking about variations of <code class="docutils literal notranslate"><span class="pre">pam</span></code> there could be one that only
returns the first result of the first-to-finish sub-program, or the
stack could be replaced by its output stack.</p>
<p>The other sub-programs would be cancelled.</p>
</div>
<div class="section" id="fulminators">
</section>
<section id="fulminators">
<h4>“Fulminators”<a class="headerlink" href="#fulminators" title="Permalink to this headline"></a></h4>
<p>Also known as “Futures” or “Promises” (by <em>everybody</em> else. “Fulinators”
is what I was going to call them when I was thinking about implementing
@ -312,44 +313,57 @@ with “asyncronous” … events?</p>
sort of thing works perfectly in Joy code Im not going to worry about
it. (And I think the Categories can deal with it anyhow? Incremental
evaluation, yeah?)</p>
</div>
</div>
</div>
</div>
</section>
</section>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">The Four Fundamental Operations of Definite Action</a><ul>
<li><a class="reference internal" href="#sequence">Sequence</a></li>
<li><a class="reference internal" href="#branch">Branch</a><ul>
<li><a class="reference internal" href="#ifte"><code class="docutils literal notranslate"><span class="pre">ifte</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#loop">Loop</a><ul>
<li><a class="reference internal" href="#while"><code class="docutils literal notranslate"><span class="pre">while</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#parallel">Parallel</a><ul>
<li><a class="reference internal" href="#cleave"><code class="docutils literal notranslate"><span class="pre">cleave</span></code></a></li>
<li><a class="reference internal" href="#apply-functions">“Apply” Functions</a></li>
<li><a class="reference internal" href="#map"><code class="docutils literal notranslate"><span class="pre">map</span></code></a></li>
<li><a class="reference internal" href="#pam"><code class="docutils literal notranslate"><span class="pre">pam</span></code></a></li>
<li><a class="reference internal" href="#handling-other-kinds-of-join">Handling Other Kinds of Join</a><ul>
<li><a class="reference internal" href="#first-to-finish">first-to-finish</a></li>
<li><a class="reference internal" href="#fulminators">“Fulminators”</a></li>
</ul>
</li>
</ul>
</li>
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -361,25 +375,24 @@ evaluation, yeah?)</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/The_Four_Operations.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -390,7 +403,7 @@ evaluation, yeah?)</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Treating Trees II: treestep &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Using x to Generate Values" href="Generator_Programs.html" />
@ -30,9 +29,11 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="treating-trees-ii-treestep">
<section id="treating-trees-ii-treestep">
<h1>Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code><a class="headerlink" href="#treating-trees-ii-treestep" title="Permalink to this headline"></a></h1>
<p>Lets consider a tree structure, similar to one described <a class="reference external" href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">“Why
functional programming matters” by John
@ -65,7 +66,7 @@ combine the result with <code class="docutils literal notranslate"><span class="
</div>
<p>(Later on well experiment with making <code class="docutils literal notranslate"><span class="pre">map</span></code> part of <code class="docutils literal notranslate"><span class="pre">C</span></code> so you can
use other combinators.)</p>
<div class="section" id="derive-the-recursive-function">
<section id="derive-the-recursive-function">
<h2>Derive the recursive function.<a class="headerlink" href="#derive-the-recursive-function" title="Permalink to this headline"></a></h2>
<p>We can begin to derive it by finding the <code class="docutils literal notranslate"><span class="pre">ifte</span></code> stage that <code class="docutils literal notranslate"><span class="pre">genrec</span></code>
will produce.</p>
@ -110,8 +111,8 @@ the desired outcome.</p>
<span class="o">==</span> <span class="p">[</span><span class="ow">not</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">uncons</span> <span class="p">[</span><span class="n">N</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="p">[</span><span class="nb">map</span> <span class="n">C</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
</div>
<div class="section" id="extract-the-givens-to-parameterize-the-program">
</section>
<section id="extract-the-givens-to-parameterize-the-program">
<h2>Extract the givens to parameterize the program.<a class="headerlink" href="#extract-the-givens-to-parameterize-the-program" title="Permalink to this headline"></a></h2>
<p>Working backwards:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="ow">not</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">uncons</span> <span class="p">[</span><span class="n">N</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="p">[</span><span class="nb">map</span> <span class="n">C</span><span class="p">]</span> <span class="n">genrec</span>
@ -134,7 +135,7 @@ the desired outcome.</p>
</pre></div>
</div>
<p>The givens are all to the left so we have our definition.</p>
<div class="section" id="alternate-extract-the-givens-to-parameterize-the-program">
<section id="alternate-extract-the-givens-to-parameterize-the-program">
<h3>(alternate) Extract the givens to parameterize the program.<a class="headerlink" href="#alternate-extract-the-givens-to-parameterize-the-program" title="Permalink to this headline"></a></h3>
<p>Working backwards:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="ow">not</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">uncons</span> <span class="p">[</span><span class="n">N</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="p">[</span><span class="nb">map</span> <span class="n">C</span><span class="p">]</span> <span class="n">genrec</span>
@ -143,32 +144,32 @@ the desired outcome.</p>
<span class="o">^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="define-treestep">
</section>
</section>
<section id="define-treestep">
<h2>Define <code class="docutils literal notranslate"><span class="pre">treestep</span></code><a class="headerlink" href="#define-treestep" title="Permalink to this headline"></a></h2>
<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><span class="p">,</span> <span class="n">define</span><span class="p">,</span> <span class="n">DefinitionWrapper</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>from notebook_preamble import D, J, V, define, DefinitionWrapper
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">&#39;&#39;&#39;</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>DefinitionWrapper.add_definitions(&#39;&#39;&#39;
<span class="s1"> _treestep_0 == [[not] swap] dip</span>
<span class="s1"> _treestep_1 == [dip] cons [uncons] swoncat</span>
<span class="s1"> treegrind == [_treestep_1 _treestep_0] dip genrec</span>
<span class="s1"> treestep == [map] swoncat treegrind</span>
_treestep_0 == [[not] swap] dip
_treestep_1 == [dip] cons [uncons] swoncat
treegrind == [_treestep_1 _treestep_0] dip genrec
treestep == [map] swoncat treegrind
<span class="s1">&#39;&#39;&#39;</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
&#39;&#39;&#39;, D)
</pre></div>
</div>
</div>
<div class="section" id="examples">
</section>
<section id="examples">
<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline"></a></h2>
<p>Consider trees, the nodes of which are integers. We can find the sum of
all nodes in a tree with this function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sumtree</span> <span class="o">==</span> <span class="p">[</span><span class="n">pop</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="nb">sum</span> <span class="o">+</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;sumtree == [pop 0] [] [sum +] treestep&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;sumtree == [pop 0] [] [sum +] treestep&#39;)
</pre></div>
</div>
<p>Running this function on an empty tree value gives zero:</p>
@ -177,7 +178,7 @@ all nodes in a tree with this function:</p>
<span class="mi">0</span>
</pre></div>
</div>
<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;[] sumtree&#39;</span><span class="p">)</span> <span class="c1"># Empty tree.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[] sumtree&#39;) # Empty tree.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span>
@ -191,68 +192,68 @@ all nodes in a tree with this function:</p>
<span class="n">n</span><span class="o">+</span><span class="n">m</span>
</pre></div>
</div>
<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;[23] sumtree&#39;</span><span class="p">)</span> <span class="c1"># No child trees.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[23] sumtree&#39;) # No child trees.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</pre></div>
</div>
<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;[23 []] sumtree&#39;</span><span class="p">)</span> <span class="c1"># Child tree, empty.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[23 []] sumtree&#39;) # Child tree, empty.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</pre></div>
</div>
<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;[23 [2 [4]] [3]] sumtree&#39;</span><span class="p">)</span> <span class="c1"># Non-empty child trees.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[23 [2 [4]] [3]] sumtree&#39;) # Non-empty child trees.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">32</span>
</pre></div>
</div>
<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;[23 [2 [8] [9]] [3] [4 []]] sumtree&#39;</span><span class="p">)</span> <span class="c1"># Etc...</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[23 [2 [8] [9]] [3] [4 []]] sumtree&#39;) # Etc...
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">49</span>
</pre></div>
</div>
<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;[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep&#39;</span><span class="p">)</span> <span class="c1"># Alternate &quot;spelling&quot;.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep&#39;) # Alternate &quot;spelling&quot;.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">49</span>
</pre></div>
</div>
<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;[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep&#39;</span><span class="p">)</span> <span class="c1"># Replace each node.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep&#39;) # Replace each node.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">23</span> <span class="p">[</span><span class="mi">23</span> <span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="p">[</span><span class="mi">23</span><span class="p">]]</span> <span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="p">[</span><span class="mi">23</span> <span class="p">[]]]</span>
</pre></div>
</div>
<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;[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep&#39;)
</pre></div>
</div>
<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">1</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="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[]]]</span>
</pre></div>
</div>
<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;[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span>
</pre></div>
</div>
<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;[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep&#39;</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep&#39;) # Combine replace and sum into one function.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span>
</pre></div>
</div>
<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 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep&#39;</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep&#39;) # Combine replace and sum into one function.
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span>
</pre></div>
</div>
</div>
<div class="section" id="redefining-the-ordered-binary-tree-in-terms-of-treestep">
</section>
<section id="redefining-the-ordered-binary-tree-in-terms-of-treestep">
<h2>Redefining the Ordered Binary Tree in terms of <code class="docutils literal notranslate"><span class="pre">treestep</span></code>.<a class="headerlink" href="#redefining-the-ordered-binary-tree-in-terms-of-treestep" title="Permalink to this headline"></a></h2>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Tree</span> <span class="o">=</span> <span class="p">[]</span> <span class="o">|</span> <span class="p">[[</span><span class="n">key</span> <span class="n">value</span><span class="p">]</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span>
</pre></div>
@ -266,7 +267,7 @@ all nodes in a tree with this function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">key</span> <span class="n">value</span><span class="p">]</span> <span class="n">N</span> <span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="nb">map</span> <span class="n">C</span>
</pre></div>
</div>
<div class="section" id="traversal">
<section id="traversal">
<h3>Traversal<a class="headerlink" href="#traversal" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">key</span> <span class="n">value</span><span class="p">]</span> <span class="n">first</span> <span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="nb">map</span> <span class="n">i</span>
<span class="n">key</span> <span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="nb">map</span> <span class="n">i</span>
@ -276,7 +277,7 @@ all nodes in a tree with this function:</p>
</pre></div>
</div>
<p>This doesnt quite work:</p>
<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;[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] [&quot;B&quot;] [first] [i] treestep&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] [&quot;B&quot;] [first] [i] treestep&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="s1">&#39;B&#39;</span> <span class="s1">&#39;B&#39;</span>
@ -298,15 +299,15 @@ depositing our results directly on the stack.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="p">[</span><span class="n">flatten</span> <span class="n">cons</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
<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;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep&#39;)
</pre></div>
</div>
<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="mi">9</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">8</span> <span class="mi">6</span> <span class="mi">7</span><span class="p">]</span>
</pre></div>
</div>
<p>There we go.</p>
</div>
<div class="section" id="in-order-traversal">
</section>
<section id="in-order-traversal">
<h3>In-order traversal<a class="headerlink" href="#in-order-traversal" title="Permalink to this headline"></a></h3>
<p>From here:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">key</span> <span class="p">[[</span><span class="n">lk</span><span class="p">]</span> <span class="p">[</span><span class="n">rk</span><span class="p">]]</span> <span class="n">C</span>
@ -321,15 +322,15 @@ depositing our results directly on the stack.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span> <span class="p">[</span><span class="n">i</span> <span class="n">roll</span><span class="o">&lt;</span> <span class="n">swons</span> <span class="n">concat</span><span class="p">]</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
<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;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll&lt; swons concat] treestep&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll&lt; swons concat] treestep&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span><span class="p">]</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="with-treegrind">
</section>
</section>
<section id="with-treegrind">
<h2>With <code class="docutils literal notranslate"><span class="pre">treegrind</span></code>?<a class="headerlink" href="#with-treegrind" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal notranslate"><span class="pre">treegrind</span></code> function doesnt include the <code class="docutils literal notranslate"><span class="pre">map</span></code> combinator, so
the <code class="docutils literal notranslate"><span class="pre">[C]</span></code> function must arrange to use some combinator on the quoted
@ -342,38 +343,38 @@ non-empty node is:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">key</span> <span class="n">value</span><span class="p">]</span> <span class="n">N</span> <span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="n">C</span>
</pre></div>
</div>
<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;[[&quot;key&quot; &quot;value&quot;] [&quot;left&quot;] [&quot;right&quot;] ] [&quot;B&quot;] [&quot;N&quot;] [&quot;C&quot;] treegrind&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[[&quot;key&quot; &quot;value&quot;] [&quot;left&quot;] [&quot;right&quot;] ] [&quot;B&quot;] [&quot;N&quot;] [&quot;C&quot;] treegrind&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">&#39;key&#39;</span> <span class="s1">&#39;value&#39;</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[[</span><span class="s1">&#39;left&#39;</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;right&#39;</span><span class="p">]]</span> <span class="p">[[</span><span class="ow">not</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;B&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">uncons</span> <span class="p">[</span><span class="s1">&#39;N&#39;</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;C&#39;</span><span class="p">]</span> <span class="n">genrec</span><span class="p">]</span> <span class="s1">&#39;C&#39;</span>
</pre></div>
</div>
</div>
<div class="section" id="treegrind-with-step">
</section>
<section id="treegrind-with-step">
<h2><code class="docutils literal notranslate"><span class="pre">treegrind</span></code> with <code class="docutils literal notranslate"><span class="pre">step</span></code><a class="headerlink" href="#treegrind-with-step" title="Permalink to this headline"></a></h2>
<p>Iteration through the nodes</p>
<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;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [&quot;N&quot;] [step] treegrind&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [&quot;N&quot;] [step] treegrind&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span>
</pre></div>
</div>
<p>Sum the nodes keys.</p>
<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;0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">44</span>
</pre></div>
</div>
<p>Rebuild the tree using <code class="docutils literal notranslate"><span class="pre">map</span></code> (imitating <code class="docutils literal notranslate"><span class="pre">treestep</span></code>.)</p>
<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;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="mi">103</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">102</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[[</span><span class="mi">109</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">105</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">104</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[[</span><span class="mi">108</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">106</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">107</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
</pre></div>
</div>
</div>
<div class="section" id="do-we-have-the-flexibility-to-reimplement-tree-get">
</section>
<section id="do-we-have-the-flexibility-to-reimplement-tree-get">
<h2>Do we have the flexibility to reimplement <code class="docutils literal notranslate"><span class="pre">Tree-get</span></code>?<a class="headerlink" href="#do-we-have-the-flexibility-to-reimplement-tree-get" title="Permalink to this headline"></a></h2>
<p>I think we do:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">B</span><span class="p">]</span> <span class="p">[</span><span class="n">N</span><span class="p">]</span> <span class="p">[</span><span class="n">C</span><span class="p">]</span> <span class="n">treegrind</span>
@ -389,12 +390,12 @@ user defined, and the per-node function is just the query key literal:</p>
</pre></div>
</div>
<p>Lets try <code class="docutils literal notranslate"><span class="pre">cmp</span></code>:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span> <span class="o">==</span> <span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o">&lt;</span><span class="p">]</span> <span class="nb">cmp</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span> <span class="o">==</span> <span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o">&lt;</span><span class="p">]</span> <span class="n">cmp</span>
<span class="p">[</span><span class="n">key</span> <span class="n">value</span><span class="p">]</span> <span class="n">query_key</span> <span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o">&lt;</span><span class="p">]</span> <span class="nb">cmp</span>
<span class="p">[</span><span class="n">key</span> <span class="n">value</span><span class="p">]</span> <span class="n">query_key</span> <span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o">&lt;</span><span class="p">]</span> <span class="n">cmp</span>
</pre></div>
</div>
<div class="section" id="the-predicate-p">
<section id="the-predicate-p">
<h3>The predicate <code class="docutils literal notranslate"><span class="pre">P</span></code><a class="headerlink" href="#the-predicate-p" title="Permalink to this headline"></a></h3>
<p>Seems pretty easy (we must preserve the value in case the keys are
equal):</p>
@ -412,7 +413,7 @@ equal):</p>
</div>
<p>(Possibly with a swap at the end? Or just swap <code class="docutils literal notranslate"><span class="pre">T&lt;</span></code> and <code class="docutils literal notranslate"><span class="pre">T&gt;</span></code>.)</p>
<p>So now:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="n">key</span> <span class="n">query_key</span> <span class="p">[</span><span class="n">T</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o">&lt;</span><span class="p">]</span> <span class="nb">cmp</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="n">key</span> <span class="n">query_key</span> <span class="p">[</span><span class="n">T</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o">&lt;</span><span class="p">]</span> <span class="n">cmp</span>
</pre></div>
</div>
<p>Becomes one of these three:</p>
@ -421,105 +422,118 @@ equal):</p>
<span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="p">[</span><span class="n">value</span><span class="p">]</span> <span class="n">T</span><span class="o">&lt;</span>
</pre></div>
</div>
</div>
<div class="section" id="e">
</section>
<section id="e">
<h3><code class="docutils literal notranslate"><span class="pre">E</span></code><a class="headerlink" href="#e" title="Permalink to this headline"></a></h3>
<p>Easy.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">E</span> <span class="o">==</span> <span class="n">roll</span><span class="o">&gt;</span> <span class="n">popop</span> <span class="n">first</span>
</pre></div>
</div>
</div>
<div class="section" id="t-and-t">
</section>
<section id="t-and-t">
<h3><code class="docutils literal notranslate"><span class="pre">T&lt;</span></code> and <code class="docutils literal notranslate"><span class="pre">T&gt;</span></code><a class="headerlink" href="#t-and-t" title="Permalink to this headline"></a></h3>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">T</span><span class="o">&lt;</span> <span class="o">==</span> <span class="n">pop</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="n">dip</span> <span class="n">i</span>
<span class="n">T</span><span class="o">&gt;</span> <span class="o">==</span> <span class="n">pop</span> <span class="p">[</span><span class="n">second</span><span class="p">]</span> <span class="n">dip</span> <span class="n">i</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="putting-it-together">
</section>
</section>
<section id="putting-it-together">
<h2>Putting it together<a class="headerlink" href="#putting-it-together" title="Permalink to this headline"></a></h2>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">T</span><span class="o">&gt;</span> <span class="o">==</span> <span class="n">pop</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="n">dip</span> <span class="n">i</span>
<span class="n">T</span><span class="o">&lt;</span> <span class="o">==</span> <span class="n">pop</span> <span class="p">[</span><span class="n">second</span><span class="p">]</span> <span class="n">dip</span> <span class="n">i</span>
<span class="n">E</span> <span class="o">==</span> <span class="n">roll</span><span class="o">&gt;</span> <span class="n">popop</span> <span class="n">first</span>
<span class="n">P</span> <span class="o">==</span> <span class="n">roll</span><span class="o">&lt;</span> <span class="p">[</span><span class="n">roll</span><span class="o">&lt;</span> <span class="n">uncons</span> <span class="n">swap</span><span class="p">]</span> <span class="n">dip</span>
<span class="n">Tree</span><span class="o">-</span><span class="n">get</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o">&lt;</span><span class="p">]</span> <span class="nb">cmp</span><span class="p">]</span> <span class="n">treegrind</span>
<span class="n">Tree</span><span class="o">-</span><span class="n">get</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="o">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o">&lt;</span><span class="p">]</span> <span class="n">cmp</span><span class="p">]</span> <span class="n">treegrind</span>
</pre></div>
</div>
<p>To me, that seems simpler than the <code class="docutils literal notranslate"><span class="pre">genrec</span></code> version.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">&#39;&#39;&#39;</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>DefinitionWrapper.add_definitions(&#39;&#39;&#39;
<span class="s1"> T&gt; == pop [first] dip i</span>
<span class="s1"> T&lt; == pop [second] dip i</span>
<span class="s1"> E == roll&gt; popop first</span>
<span class="s1"> P == roll&lt; [roll&lt; uncons swap] dip</span>
T&gt; == pop [first] dip i
T&lt; == pop [second] dip i
E == roll&gt; popop first
P == roll&lt; [roll&lt; uncons swap] dip
<span class="s1"> Tree-get == [P [T&gt;] [E] [T&lt;] cmp] treegrind</span>
Tree-get == [P [T&gt;] [E] [T&lt;] cmp] treegrind
<span class="s1">&#39;&#39;&#39;</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
&#39;&#39;&#39;, D)
</pre></div>
</div>
<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;&#39;&#39;</span><span class="se">\</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;&#39;&#39;\
<span class="s1">[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]</span>
[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]
<span class="s1">[] [5] Tree-get</span>
[] [5] Tree-get
<span class="s1">&#39;&#39;&#39;</span><span class="p">)</span>
&#39;&#39;&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
</pre></div>
</div>
<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;&#39;&#39;</span><span class="se">\</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;&#39;&#39;\
<span class="s1">[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]</span>
[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]
<span class="s1">[pop &quot;nope&quot;] [25] Tree-get</span>
[pop &quot;nope&quot;] [25] Tree-get
<span class="s1">&#39;&#39;&#39;</span><span class="p">)</span>
&#39;&#39;&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;nope&#39;</span>
</pre></div>
</div>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a><ul>
<li><a class="reference internal" href="#derive-the-recursive-function">Derive the recursive function.</a></li>
<li><a class="reference internal" href="#extract-the-givens-to-parameterize-the-program">Extract the givens to parameterize the program.</a><ul>
<li><a class="reference internal" href="#alternate-extract-the-givens-to-parameterize-the-program">(alternate) Extract the givens to parameterize the program.</a></li>
</ul>
</li>
<li><a class="reference internal" href="#define-treestep">Define <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li><a class="reference internal" href="#examples">Examples</a></li>
<li><a class="reference internal" href="#redefining-the-ordered-binary-tree-in-terms-of-treestep">Redefining the Ordered Binary Tree in terms of <code class="docutils literal notranslate"><span class="pre">treestep</span></code>.</a><ul>
<li><a class="reference internal" href="#traversal">Traversal</a></li>
<li><a class="reference internal" href="#in-order-traversal">In-order traversal</a></li>
</ul>
</li>
<li><a class="reference internal" href="#with-treegrind">With <code class="docutils literal notranslate"><span class="pre">treegrind</span></code>?</a></li>
<li><a class="reference internal" href="#treegrind-with-step"><code class="docutils literal notranslate"><span class="pre">treegrind</span></code> with <code class="docutils literal notranslate"><span class="pre">step</span></code></a></li>
<li><a class="reference internal" href="#do-we-have-the-flexibility-to-reimplement-tree-get">Do we have the flexibility to reimplement <code class="docutils literal notranslate"><span class="pre">Tree-get</span></code>?</a><ul>
<li><a class="reference internal" href="#the-predicate-p">The predicate <code class="docutils literal notranslate"><span class="pre">P</span></code></a></li>
<li><a class="reference internal" href="#e"><code class="docutils literal notranslate"><span class="pre">E</span></code></a></li>
<li><a class="reference internal" href="#t-and-t"><code class="docutils literal notranslate"><span class="pre">T&lt;</span></code> and <code class="docutils literal notranslate"><span class="pre">T&gt;</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#putting-it-together">Putting it together</a></li>
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -531,25 +545,24 @@ equal):</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Treestep.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -560,7 +573,7 @@ equal):</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Type Checking &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="No Updates" href="NoUpdates.html" />
@ -30,37 +29,39 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="type-checking">
<section id="type-checking">
<h1>Type Checking<a class="headerlink" href="#type-checking" title="Permalink to this headline"></a></h1>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">sys</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>import logging, sys
<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>
<span class="p">)</span>
logging.basicConfig(
format=&#39;%(message)s&#39;,
stream=sys.stdout,
level=logging.INFO,
)
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.utils.types</span> <span class="k">import</span> <span class="p">(</span>
<span class="n">doc_from_stack_effect</span><span class="p">,</span>
<span class="n">infer</span><span class="p">,</span>
<span class="n">reify</span><span class="p">,</span>
<span class="n">unify</span><span class="p">,</span>
<span class="n">FUNCTIONS</span><span class="p">,</span>
<span class="n">JoyTypeError</span><span class="p">,</span>
<span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>from joy.utils.types import (
doc_from_stack_effect,
infer,
reify,
unify,
FUNCTIONS,
JoyTypeError,
)
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">D</span> <span class="o">=</span> <span class="n">FUNCTIONS</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">del</span> <span class="n">D</span><span class="p">[</span><span class="s1">&#39;product&#39;</span><span class="p">]</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">D</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>D = FUNCTIONS.copy()
del D[&#39;product&#39;]
globals().update(D)
</pre></div>
</div>
<div class="section" id="an-example">
<section id="an-example">
<h2>An Example<a class="headerlink" href="#an-example" title="Permalink to this headline"></a></h2>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</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">rrest</span><span class="p">,</span> <span class="n">ccons</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>fi, fo = infer(pop, swap, rolldown, rrest, ccons)[0]
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>25 (--) ∘ pop swap rolldown rrest ccons
@ -71,61 +72,61 @@
40 ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) ∘
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>print doc_from_stack_effect(fi, fo)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a4</span> <span class="n">a5</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a3</span> <span class="o">...</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.parser</span> <span class="k">import</span> <span class="n">text_to_expression</span>
<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="k">import</span> <span class="n">stack_to_string</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>from joy.parser import text_to_expression
from joy.utils.stack import stack_to_string
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;0 1 2 [3 4]&#39;</span><span class="p">)</span> <span class="c1"># reverse order</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>e = text_to_expression(&#39;0 1 2 [3 4]&#39;) # reverse order
print stack_to_string(e)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">4</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">u</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>u = unify(e, fi)[0]
u
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">a2</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a4</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">a5</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</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="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>g = reify(u, (fi, fo))
print doc_from_stack_effect(*g)
</pre></div>
</div>
<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="mi">3</span> <span class="mi">4</span> <span class="p">]</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="p">])</span>
</pre></div>
</div>
</div>
<div class="section" id="unification-works-in-reverse">
</section>
<section id="unification-works-in-reverse">
<h2>Unification Works “in Reverse”<a class="headerlink" href="#unification-works-in-reverse" title="Permalink to this headline"></a></h2>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;[2 3]&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>e = text_to_expression(&#39;[2 3]&#39;)
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fo</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># output side, not input side</span>
<span class="n">u</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>u = unify(e, fo)[0] # output side, not input side
u
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a2</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</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="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>g = reify(u, (fi, fo))
print doc_from_stack_effect(*g)
</pre></div>
</div>
<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">a4</span> <span class="n">a5</span> <span class="p">]</span> <span class="mi">3</span> <span class="mi">2</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="p">])</span>
</pre></div>
</div>
</div>
<div class="section" id="failing-a-check">
</section>
<section id="failing-a-check">
<h2>Failing a Check<a class="headerlink" href="#failing-a-check" title="Permalink to this headline"></a></h2>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>fi, fo = infer(dup, mul)[0]
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>25 (--) ∘ dup mul
@ -134,40 +135,71 @@
31 (i1 -- i2) ∘
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;&quot;two&quot;&#39;</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>e = text_to_expression(&#39;&quot;two&quot;&#39;)
print stack_to_string(e)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;two&#39;</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)</span>
<span class="k">except</span> <span class="n">JoyTypeError</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">err</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>try:
unify(e, fi)
except JoyTypeError, err:
print err
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Cannot</span> <span class="n">unify</span> <span class="s1">&#39;two&#39;</span> <span class="ow">and</span> <span class="n">f1</span><span class="o">.</span>
</pre></div>
</div>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Type Checking</a><ul>
<li><a class="reference internal" href="#an-example">An Example</a></li>
<li><a class="reference internal" href="#unification-works-in-reverse">Unification Works “in Reverse”</a></li>
<li><a class="reference internal" href="#failing-a-check">Failing a Check</a></li>
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -179,25 +211,24 @@
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/TypeChecking.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -208,7 +239,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Traversing Datastructures with Zippers &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="The Blissful Elegance of Typing Joy" href="Types.html" />
@ -30,9 +29,11 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="traversing-datastructures-with-zippers">
<section id="traversing-datastructures-with-zippers">
<h1>Traversing Datastructures with Zippers<a class="headerlink" href="#traversing-datastructures-with-zippers" title="Permalink to this headline"></a></h1>
<p>This notebook is about using the “zipper” with joy datastructures. See
the <a class="reference external" href="https://en.wikipedia.org/wiki/Zipper_%28data_structure%29">Zipper wikipedia
@ -41,24 +42,24 @@ the original paper: <a class="reference external" href="https://www.st.cs.uni-sa
Huet</a></p>
<p>Given a datastructure on the stack we can navigate through it, modify
it, and rebuild it using the “zipper” technique.</p>
<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">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>from notebook_preamble import J, V, define
</pre></div>
</div>
<div class="section" id="trees">
<section id="trees">
<h2>Trees<a class="headerlink" href="#trees" title="Permalink to this headline"></a></h2>
<p>In Joypy there arent any complex datastructures, just ints, floats,
strings, Symbols (strings that are names of functions) and sequences
(aka lists, aka quoted literals, aka aggregates, etc…), but we can build
<a class="reference external" href="https://en.wikipedia.org/wiki/Tree_%28data_structure%29">trees</a> out
of sequences.</p>
<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;[1 [2 [3 4 25 6] 7] 8]&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1 [2 [3 4 25 6] 7] 8]&#39;)
</pre></div>
</div>
<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">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="zipper-in-joy">
</section>
<section id="zipper-in-joy">
<h2>Zipper in Joy<a class="headerlink" href="#zipper-in-joy" title="Permalink to this headline"></a></h2>
<p>Zippers work by keeping track of the current item, the already-seen
items, and the yet-to-be seen items as you traverse a datastructure (the
@ -74,13 +75,13 @@ datastructure used to keep track of these items is the zipper.)</p>
show the trace so you can see how it works. If we were going to use
these a lot it would make sense to write Python versions for efficiency,
but see below.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;z-down == [] swap uncons swap&#39;</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">&#39;z-up == swons swap shunt&#39;</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">&#39;z-right == [swons] cons dip uncons swap&#39;</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">&#39;z-left == swons [uncons swap] dip swap&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;z-down == [] swap uncons swap&#39;)
define(&#39;z-up == swons swap shunt&#39;)
define(&#39;z-right == [swons] cons dip uncons swap&#39;)
define(&#39;z-left == swons [uncons swap] dip swap&#39;)
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;[1 [2 [3 4 25 6] 7] 8] z-down&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>V(&#39;[1 [2 [3 4 25 6] 7] 8] z-down&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></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="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="n">z</span><span class="o">-</span><span class="n">down</span>
@ -92,7 +93,7 @@ but see below.</p>
<span class="p">[]</span> <span class="p">[[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="mi">1</span> <span class="o">.</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;[] [[2 [3 4 25 6] 7] 8] 1 z-right&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>V(&#39;[] [[2 [3 4 25 6] 7] 8] 1 z-right&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</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="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="mi">1</span> <span class="n">z</span><span class="o">-</span><span class="n">right</span>
@ -112,43 +113,43 @@ but see below.</p>
<span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</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="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
<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;[1] [8] [2 [3 4 25 6] 7] z-down&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1] [8] [2 [3 4 25 6] 7] z-down&#39;)
</pre></div>
</div>
<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="mi">8</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">2</span>
</pre></div>
</div>
<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;[1] [8] [] [[3 4 25 6] 7] 2 z-right&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1] [8] [] [[3 4 25 6] 7] 2 z-right&#39;)
</pre></div>
</div>
<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="mi">8</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">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span>
</pre></div>
</div>
<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;[1] [8] [2] [7] [3 4 25 6] z-down&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1] [8] [2] [7] [3 4 25 6] z-down&#39;)
</pre></div>
</div>
<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="mi">8</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">7</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">3</span>
</pre></div>
</div>
<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;[1] [8] [2] [7] [] [4 25 6] 3 z-right&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1] [8] [2] [7] [] [4 25 6] 3 z-right&#39;)
</pre></div>
</div>
<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="mi">8</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">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">4</span>
</pre></div>
</div>
<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;[1] [8] [2] [7] [3] [25 6] 4 z-right&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1] [8] [2] [7] [3] [25 6] 4 z-right&#39;)
</pre></div>
</div>
<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="mi">8</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">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">25</span>
</pre></div>
</div>
<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;[1] [8] [2] [7] [4 3] [6] 25 sqr&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1] [8] [2] [7] [4 3] [6] 25 sqr&#39;)
</pre></div>
</div>
<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="mi">8</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">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">625</span>
</pre></div>
</div>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;[1] [8] [2] [7] [4 3] [6] 625 z-up&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>V(&#39;[1] [8] [2] [7] [4 3] [6] 625 z-up&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></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">8</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">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">625</span> <span class="n">z</span><span class="o">-</span><span class="n">up</span>
@ -167,24 +168,24 @@ but see below.</p>
<span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</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">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
<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;[1] [8] [2] [7] [3 4 625 6] z-up&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1] [8] [2] [7] [3 4 625 6] z-up&#39;)
</pre></div>
</div>
<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="mi">8</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="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span>
</pre></div>
</div>
<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;[1] [8] [2 [3 4 625 6] 7] z-up&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1] [8] [2 [3 4 625 6] 7] z-up&#39;)
</pre></div>
</div>
<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">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="dip-and-infra">
</section>
<section id="dip-and-infra">
<h2><code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code><a class="headerlink" href="#dip-and-infra" title="Permalink to this headline"></a></h2>
<p>In Joy we have the <code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code> combinators which can “target”
or “address” any particular item in a Joy tree structure.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>V(&#39;[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></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="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="p">[[[[[[</span><span class="n">sqr</span><span class="p">]</span> <span class="n">dipd</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">infra</span>
@ -222,8 +223,8 @@ the subject datastructure. Instead of maintaining temporary results on
the stack they are pushed into the pending expression (continuation).
When <code class="docutils literal notranslate"><span class="pre">sqr</span></code> has run the rest of the pending expression rebuilds the
datastructure.</p>
</div>
<div class="section" id="z">
</section>
<section id="z">
<h2><code class="docutils literal notranslate"><span class="pre">Z</span></code><a class="headerlink" href="#z" title="Permalink to this headline"></a></h2>
<p>Imagine a function <code class="docutils literal notranslate"><span class="pre">Z</span></code> that accepts a sequence of <code class="docutils literal notranslate"><span class="pre">dip</span></code> and
<code class="docutils literal notranslate"><span class="pre">infra</span></code> combinators, a quoted program <code class="docutils literal notranslate"><span class="pre">[Q]</span></code>, and a datastructure to
@ -235,11 +236,11 @@ been embedded in a nested series of quoted programs, e.g.:</p>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">Z</span></code> function isnt hard to make.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;Z == [[] cons cons] step i&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>define(&#39;Z == [[] cons cons] step i&#39;)
</pre></div>
</div>
<p>Here it is in action in a simplified scenario.</p>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;1 [2 3 4] Z&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>V(&#39;1 [2 3 4] Z&#39;)
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span> <span class="n">Z</span>
@ -272,14 +273,14 @@ been embedded in a nested series of quoted programs, e.g.:</p>
</pre></div>
</div>
<p>And here it is doing the main thing.</p>
<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;[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z&#39;</span><span class="p">)</span>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span>J(&#39;[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z&#39;)
</pre></div>
</div>
<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">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
</pre></div>
</div>
</div>
<div class="section" id="addressing">
</section>
<section id="addressing">
<h2>Addressing<a class="headerlink" href="#addressing" title="Permalink to this headline"></a></h2>
<p>Because we are only using two combinators we could replace the list with
a string made from only two characters.</p>
@ -290,8 +291,8 @@ a string made from only two characters.</p>
</div>
<p>The string can be considered a name or address for an item in the
subject datastructure.</p>
</div>
<div class="section" id="determining-the-right-path-for-an-item-in-a-tree">
</section>
<section id="determining-the-right-path-for-an-item-in-a-tree">
<h2>Determining the right “path” for an item in a tree.<a class="headerlink" href="#determining-the-right-path-for-an-item-in-a-tree" title="Permalink to this headline"></a></h2>
<p>Its easy to read off (in reverse) the right sequence of “d” and “i”
from the subject datastructure:</p>
@ -299,27 +300,55 @@ from the subject datastructure:</p>
i d i d i d d Bingo!
</pre></div>
</div>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Traversing Datastructures with Zippers</a><ul>
<li><a class="reference internal" href="#trees">Trees</a></li>
<li><a class="reference internal" href="#zipper-in-joy">Zipper in Joy</a></li>
<li><a class="reference internal" href="#dip-and-infra"><code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code></a></li>
<li><a class="reference internal" href="#z"><code class="docutils literal notranslate"><span class="pre">Z</span></code></a></li>
<li><a class="reference internal" href="#addressing">Addressing</a></li>
<li><a class="reference internal" href="#determining-the-right-path-for-an-item-in-a-tree">Determining the right “path” for an item in a tree.</a></li>
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -331,25 +360,24 @@ i d i d i d d Bingo!
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Zipper.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -360,7 +388,7 @@ i d i d i d d Bingo!
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Essays about Programming in Joy &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script type="text/javascript" src="../_static/documentation_options.js"></script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/alabaster.css" />
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Developing a Program in Joy" href="Developing.html" />
@ -30,9 +29,11 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="essays-about-programming-in-joy">
<section id="essays-about-programming-in-joy">
<h1>Essays about Programming in Joy<a class="headerlink" href="#essays-about-programming-in-joy" title="Permalink to this headline"></a></h1>
<p>These essays are adapted from Jupyter notebooks. I hope to have those hosted somewhere where people can view them “live” and interact with them, possibly on MS Azure. For now, Sphinx does such a great job rendering the HTML that I am copying over some notebooks in ReST format and hand-editing them into these documents.</p>
<div class="toctree-wrapper compound">
@ -156,14 +157,55 @@
</li>
</ul>
</div>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Essays about Programming in Joy</a><ul>
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
@ -172,25 +214,24 @@
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/index.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -201,7 +242,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Parsing Text into Joy Expressions &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Tracing Joy Execution" href="pretty.html" />
@ -30,12 +29,14 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="parsing-text-into-joy-expressions">
<section id="parsing-text-into-joy-expressions">
<h1>Parsing Text into Joy Expressions<a class="headerlink" href="#parsing-text-into-joy-expressions" title="Permalink to this headline"></a></h1>
<p>TODO: example…</p>
<div class="section" id="module-joy.parser">
<section id="module-joy.parser">
<span id="joy-parser"></span><h2><code class="docutils literal notranslate"><span class="pre">joy.parser</span></code><a class="headerlink" href="#module-joy.parser" title="Permalink to this headline"></a></h2>
<p>This module exports a single function for converting text to a joy
expression as well as a single Symbol class and a single Exception type.</p>
@ -51,60 +52,78 @@ literal value (integer, float, string, or Joy expression) or a function
symbol. Function symbols are unquoted strings and cannot contain square
brackets. Terms must be separated by blanks, which can be omitted
around square brackets.</p>
<dl class="exception">
<dt id="joy.parser.ParseError">
<em class="property">exception </em><code class="descclassname">joy.parser.</code><code class="descname">ParseError</code><a class="reference internal" href="_modules/joy/parser.html#ParseError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.parser.ParseError" title="Permalink to this definition"></a></dt>
<dl class="py exception">
<dt class="sig sig-object py" id="joy.parser.ParseError">
<em class="property"><span class="pre">exception</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">joy.parser.</span></span><span class="sig-name descname"><span class="pre">ParseError</span></span><a class="reference internal" href="_modules/joy/parser.html#ParseError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.parser.ParseError" title="Permalink to this definition"></a></dt>
<dd><p>Raised when there is a error while parsing text.</p>
</dd></dl>
<dl class="class">
<dt id="joy.parser.Symbol">
<em class="property">class </em><code class="descclassname">joy.parser.</code><code class="descname">Symbol</code><a class="reference internal" href="_modules/joy/parser.html#Symbol"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.parser.Symbol" title="Permalink to this definition"></a></dt>
<dl class="py class">
<dt class="sig sig-object py" id="joy.parser.Symbol">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">joy.parser.</span></span><span class="sig-name descname"><span class="pre">Symbol</span></span><a class="reference internal" href="_modules/joy/parser.html#Symbol"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.parser.Symbol" title="Permalink to this definition"></a></dt>
<dd><p>A string class that represents Joy function names.</p>
</dd></dl>
<dl class="function">
<dt id="joy.parser.text_to_expression">
<code class="descclassname">joy.parser.</code><code class="descname">text_to_expression</code><span class="sig-paren">(</span><em>text</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/parser.html#text_to_expression"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.parser.text_to_expression" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.parser.text_to_expression">
<span class="sig-prename descclassname"><span class="pre">joy.parser.</span></span><span class="sig-name descname"><span class="pre">text_to_expression</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">text</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/parser.html#text_to_expression"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.parser.text_to_expression" title="Permalink to this definition"></a></dt>
<dd><p>Convert a string to a Joy expression.</p>
<p>When supplied with a string this function returns a Python datastructure
that represents the Joy datastructure described by the text expression.
Any unbalanced square brackets will raise a ParseError.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>text</strong> (<em>str</em>) Text to convert.</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">stack</td>
</tr>
<tr class="field-odd field"><th class="field-name">Raises:</th><td class="field-body"><a class="reference internal" href="#joy.parser.ParseError" title="joy.parser.ParseError"><strong>ParseError</strong></a> if the parse fails.</td>
</tr>
</tbody>
</table>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>text</strong> (<em>str</em>) Text to convert.</p>
</dd>
<dt class="field-even">Return type</dt>
<dd class="field-even"><p>stack</p>
</dd>
<dt class="field-odd">Raises</dt>
<dd class="field-odd"><p><a class="reference internal" href="#joy.parser.ParseError" title="joy.parser.ParseError"><strong>ParseError</strong></a> if the parse fails.</p>
</dd>
</dl>
</dd></dl>
</div>
<div class="section" id="parser-internals">
</section>
<section id="parser-internals">
<h2>Parser Internals<a class="headerlink" href="#parser-internals" title="Permalink to this headline"></a></h2>
<p>TODO: Document things like the regular expressions used for tokenizing, and the re.Scanner, etc…</p>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Parsing Text into Joy Expressions</a><ul>
<li><a class="reference internal" href="#module-joy.parser"><code class="docutils literal notranslate"><span class="pre">joy.parser</span></code></a></li>
<li><a class="reference internal" href="#parser-internals">Parser Internals</a></li>
<h1 class="logo"><a href="index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Parsing Text into Joy Expressions</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#module-joy.parser"><code class="docutils literal notranslate"><span class="pre">joy.parser</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="#parser-internals">Parser Internals</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -114,25 +133,24 @@ Any unbalanced square brackets will raise a ParseError.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/parser.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -143,7 +161,7 @@ Any unbalanced square brackets will raise a ParseError.</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Tracing Joy Execution &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Function Reference" href="library.html" />
@ -30,11 +29,13 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="tracing-joy-execution">
<section id="tracing-joy-execution">
<h1>Tracing Joy Execution<a class="headerlink" href="#tracing-joy-execution" title="Permalink to this headline"></a></h1>
<div class="section" id="module-joy.utils.pretty_print">
<section id="module-joy.utils.pretty_print">
<span id="joy-utils-pretty-print"></span><h2><code class="docutils literal notranslate"><span class="pre">joy.utils.pretty_print</span></code><a class="headerlink" href="#module-joy.utils.pretty_print" title="Permalink to this headline"></a></h2>
<p>Pretty printing support, e.g.:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>Joy? [23 18 * 99 +] trace
@ -53,89 +54,97 @@ joy?
<p>On each line the stack is printed with the top to the left, then a
bullet symbol,``•<a href="#id1"><span class="problematic" id="id2">``</span></a>, to represent the current locus of processing, then
the pending expression to the right.</p>
<dl class="class">
<dt id="joy.utils.pretty_print.TracePrinter">
<em class="property">class </em><code class="descclassname">joy.utils.pretty_print.</code><code class="descname">TracePrinter</code><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter" title="Permalink to this definition"></a></dt>
<dl class="py class">
<dt class="sig sig-object py" id="joy.utils.pretty_print.TracePrinter">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">joy.utils.pretty_print.</span></span><span class="sig-name descname"><span class="pre">TracePrinter</span></span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter" title="Permalink to this definition"></a></dt>
<dd><p>This is what does the formatting. You instantiate it and pass the <code class="docutils literal notranslate"><span class="pre">viewer()</span></code>
method to the <a class="reference internal" href="joy.html#joy.joy.joy" title="joy.joy.joy"><code class="xref py py-func docutils literal notranslate"><span class="pre">joy.joy.joy()</span></code></a> function, then print it to see the
trace.</p>
<dl class="method">
<dt id="joy.utils.pretty_print.TracePrinter.go">
<code class="descname">go</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter.go"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter.go" title="Permalink to this definition"></a></dt>
<dl class="py method">
<dt class="sig sig-object py" id="joy.utils.pretty_print.TracePrinter.go">
<span class="sig-name descname"><span class="pre">go</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter.go"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter.go" title="Permalink to this definition"></a></dt>
<dd><p>Return a list of strings, one for each entry in the history, prefixed
with enough spaces to align all the interpreter dots.</p>
<p>This method is called internally by the <code class="docutils literal notranslate"><span class="pre">__str__()</span></code> method.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">list(str)</td>
</tr>
</tbody>
</table>
<dl class="field-list simple">
<dt class="field-odd">Return type</dt>
<dd class="field-odd"><p>list(str)</p>
</dd>
</dl>
</dd></dl>
<dl class="method">
<dt id="joy.utils.pretty_print.TracePrinter.viewer">
<code class="descname">viewer</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter.viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter.viewer" title="Permalink to this definition"></a></dt>
<dl class="py method">
<dt class="sig sig-object py" id="joy.utils.pretty_print.TracePrinter.viewer">
<span class="sig-name descname"><span class="pre">viewer</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">stack</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">expression</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter.viewer"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter.viewer" title="Permalink to this definition"></a></dt>
<dd><p>Record the current stack and expression in the TracePrinters history.
Pass this method as the <code class="docutils literal notranslate"><span class="pre">viewer</span></code> argument to the <a class="reference internal" href="joy.html#joy.joy.joy" title="joy.joy.joy"><code class="xref py py-func docutils literal notranslate"><span class="pre">joy.joy.joy()</span></code></a> function.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
<li><strong>quote</strong> (<em>stack</em>) A stack.</li>
<li><strong>expression</strong> (<em>stack</em>) A stack.</li>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>quote</strong> (<em>stack</em>) A stack.</p></li>
<li><p><strong>expression</strong> (<em>stack</em>) A stack.</p></li>
</ul>
</td>
</tr>
</tbody>
</table>
</dd>
</dl>
</dd></dl>
</dd></dl>
<dl class="function">
<dt id="joy.utils.pretty_print.trace">
<code class="descclassname">joy.utils.pretty_print.</code><code class="descname">trace</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#trace"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.trace" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.utils.pretty_print.trace">
<span class="sig-prename descclassname"><span class="pre">joy.utils.pretty_print.</span></span><span class="sig-name descname"><span class="pre">trace</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">stack</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">expression</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">dictionary</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#trace"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.pretty_print.trace" title="Permalink to this definition"></a></dt>
<dd><p>Evaluate a Joy expression on a stack and print a trace.</p>
<p>This function is just like the <cite>i</cite> combinator but it also prints a
trace of the evaluation</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>stack</strong> (<em>stack</em>) The stack.</li>
<li><strong>expression</strong> (<em>stack</em>) The expression to evaluate.</li>
<li><strong>dictionary</strong> (<em>dict</em>) A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</li>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>stack</strong> (<em>stack</em>) The stack.</p></li>
<li><p><strong>expression</strong> (<em>stack</em>) The expression to evaluate.</p></li>
<li><p><strong>dictionary</strong> (<em>dict</em>) A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</p></li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">(stack, (), dictionary)</p>
</td>
</tr>
</tbody>
</table>
</dd>
<dt class="field-even">Return type</dt>
<dd class="field-even"><p>(stack, (), dictionary)</p>
</dd>
</dl>
</dd></dl>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Tracing Joy Execution</a><ul>
<li><a class="reference internal" href="#module-joy.utils.pretty_print"><code class="docutils literal notranslate"><span class="pre">joy.utils.pretty_print</span></code></a></li>
<h1 class="logo"><a href="index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Tracing Joy Execution</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#module-joy.utils.pretty_print"><code class="docutils literal notranslate"><span class="pre">joy.utils.pretty_print</span></code></a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -145,25 +154,24 @@ trace of the evaluation</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/pretty.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -174,7 +182,7 @@ trace of the evaluation</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,17 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Python Module Index &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
@ -31,6 +29,8 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
@ -84,10 +84,34 @@
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
@ -95,17 +119,23 @@
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -116,7 +146,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,27 +1,23 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Search &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/searchtools.js"></script>
<script src="_static/language_data.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="#" />
<script type="text/javascript">
jQuery(function() { Search.loadIndex("searchindex.js"); });
</script>
<script type="text/javascript" id="searchindexloader"></script>
<script src="searchindex.js" defer></script>
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
@ -36,43 +32,84 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1 id="search-documentation">Search</h1>
<div id="fallback" class="admonition warning">
<script type="text/javascript">$('#fallback').hide();</script>
<noscript>
<div class="admonition warning">
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
</noscript>
<p>
From here you can search these documents. Enter your search
words into the box below and click "search". Note that the search
function will automatically search for all of the words. Pages
containing fewer words won't appear in the result list.
Searching for multiple words only shows matches that contain
all words.
</p>
<form action="" method="get">
<input type="text" name="q" value="" />
<input type="text" name="q" aria-labelledby="search-documentation" value="" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
<div id="search-results">
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper"><div class="relations">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
@ -83,7 +120,7 @@
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

File diff suppressed because one or more lines are too long

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Stack or Quote or Sequence or List… &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Parsing Text into Joy Expressions" href="parser.html" />
@ -30,11 +29,13 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="stack-or-quote-or-sequence-or-list">
<section id="stack-or-quote-or-sequence-or-list">
<h1>Stack or Quote or Sequence or List…<a class="headerlink" href="#stack-or-quote-or-sequence-or-list" title="Permalink to this headline"></a></h1>
<div class="section" id="module-joy.utils.stack">
<section id="module-joy.utils.stack">
<span id="joy-utils-stack"></span><h2><code class="docutils literal notranslate"><span class="pre">joy.utils.stack</span></code><a class="headerlink" href="#module-joy.utils.stack" title="Permalink to this headline"></a></h2>
<p>When talking about Joy we use the terms “stack”, “quote”, “sequence”,
“list”, and others to mean the same thing: a simple linear datatype that
@ -44,7 +45,7 @@ values from (at least) one end.</p>
venerable two-tuple recursive sequence datastructure, where the
empty tuple <code class="docutils literal notranslate"><span class="pre">()</span></code> is the empty stack and <code class="docutils literal notranslate"><span class="pre">(head,</span> <span class="pre">rest)</span></code> gives the
recursive form of a stack with one or more items on it:</p>
<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="p">()</span> <span class="o">|</span> <span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stack</span> <span class="o">:=</span> <span class="p">()</span> <span class="o">|</span> <span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
</pre></div>
</div>
<p>Putting some numbers onto a stack:</p>
@ -59,7 +60,7 @@ recursive form of a stack with one or more items on it:</p>
means we can directly “unpack” the expected arguments to a Joy function.</p>
<p>For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">dup</span><span class="p">((</span><span class="n">head</span><span class="p">,</span> <span class="n">tail</span><span class="p">)):</span>
<span class="k">return</span> <span class="n">head</span><span class="p">,</span> <span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="n">tail</span><span class="p">)</span>
<span class="k">return</span> <span class="n">head</span><span class="p">,</span> <span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="n">tail</span><span class="p">)</span>
</pre></div>
</div>
<p>We replace the argument “stack” by the expected structure of the stack,
@ -71,8 +72,8 @@ where they would be redundant.)</p>
web page, doesnt handle tuples in the function parameters. And in Python 3, this
syntax was removed entirely. Instead you would have to write:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">dup</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="n">head</span><span class="p">,</span> <span class="n">tail</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="n">head</span><span class="p">,</span> <span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="n">tail</span><span class="p">)</span>
<span class="n">head</span><span class="p">,</span> <span class="n">tail</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="n">head</span><span class="p">,</span> <span class="p">(</span><span class="n">head</span><span class="p">,</span> <span class="n">tail</span><span class="p">)</span>
</pre></div>
</div>
<p>We have two very simple functions, one to build up a stack from a Python
@ -80,155 +81,168 @@ iterable and another to iterate through a stack and yield its items
one-by-one in order. There are also two functions to generate string representations
of stacks. They only differ in that one prints the terms in stack from left-to-right while the other prints from right-to-left. In both functions <em>internal stacks</em> are
printed left-to-right. These functions are written to support <a class="reference internal" href="pretty.html"><span class="doc">Tracing Joy Execution</span></a>.</p>
<dl class="function">
<dt id="joy.utils.stack.concat">
<code class="descclassname">joy.utils.stack.</code><code class="descname">concat</code><span class="sig-paren">(</span><em>quote</em>, <em>expression</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#concat"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.concat" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.utils.stack.concat">
<span class="sig-prename descclassname"><span class="pre">joy.utils.stack.</span></span><span class="sig-name descname"><span class="pre">concat</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">quote</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">expression</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#concat"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.stack.concat" title="Permalink to this definition"></a></dt>
<dd><p>Concatinate quote onto expression.</p>
<p>In joy [1 2] [3 4] would become [1 2 3 4].</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>quote</strong> (<em>stack</em>) A stack.</li>
<li><strong>expression</strong> (<em>stack</em>) A stack.</li>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>quote</strong> (<em>stack</em>) A stack.</p></li>
<li><p><strong>expression</strong> (<em>stack</em>) A stack.</p></li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Raises:</th><td class="field-body"><p class="first"><strong>RuntimeError</strong> if quote is larger than sys.getrecursionlimit().</p>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">stack</p>
</td>
</tr>
</tbody>
</table>
</dd>
<dt class="field-even">Raises</dt>
<dd class="field-even"><p><strong>RuntimeError</strong> if quote is larger than sys.getrecursionlimit().</p>
</dd>
<dt class="field-odd">Return type</dt>
<dd class="field-odd"><p>stack</p>
</dd>
</dl>
</dd></dl>
<dl class="function">
<dt id="joy.utils.stack.expression_to_string">
<code class="descclassname">joy.utils.stack.</code><code class="descname">expression_to_string</code><span class="sig-paren">(</span><em>expression</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#expression_to_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.expression_to_string" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.utils.stack.dnd">
<span class="sig-prename descclassname"><span class="pre">joy.utils.stack.</span></span><span class="sig-name descname"><span class="pre">dnd</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">stack</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">from_index</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">to_index</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#dnd"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.stack.dnd" title="Permalink to this definition"></a></dt>
<dd><p>Given a stack and two indices return a rearranged stack.
First remove the item at from_index and then insert it at to_index,
the second index is relative to the stack after removal of the item
at from_index.</p>
<p>This function reuses all of the items and as much of the stack as it
can. Its meant to be used by remote clients to support drag-n-drop
rearranging of the stack from e.g. the StackListbox.</p>
</dd></dl>
<dl class="py function">
<dt class="sig sig-object py" id="joy.utils.stack.expression_to_string">
<span class="sig-prename descclassname"><span class="pre">joy.utils.stack.</span></span><span class="sig-name descname"><span class="pre">expression_to_string</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">expression</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#expression_to_string"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.stack.expression_to_string" title="Permalink to this definition"></a></dt>
<dd><p>Return a “pretty print” string for a expression.</p>
<p>The items are written left-to-right:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">top</span><span class="p">,</span> <span class="p">(</span><span class="n">second</span><span class="p">,</span> <span class="o">...</span><span class="p">))</span> <span class="o">-&gt;</span> <span class="s1">&#39;top second ...&#39;</span>
</pre></div>
</div>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>expression</strong> (<em>stack</em>) A stack.</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">str</td>
</tr>
</tbody>
</table>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>expression</strong> (<em>stack</em>) A stack.</p>
</dd>
<dt class="field-even">Return type</dt>
<dd class="field-even"><p>str</p>
</dd>
</dl>
</dd></dl>
<dl class="function">
<dt id="joy.utils.stack.iter_stack">
<code class="descclassname">joy.utils.stack.</code><code class="descname">iter_stack</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#iter_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.iter_stack" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.utils.stack.iter_stack">
<span class="sig-prename descclassname"><span class="pre">joy.utils.stack.</span></span><span class="sig-name descname"><span class="pre">iter_stack</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">stack</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#iter_stack"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.stack.iter_stack" title="Permalink to this definition"></a></dt>
<dd><p>Iterate through the items on the stack.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>stack</strong> (<em>stack</em>) A stack.</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">iterator</td>
</tr>
</tbody>
</table>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>stack</strong> (<em>stack</em>) A stack.</p>
</dd>
<dt class="field-even">Return type</dt>
<dd class="field-even"><p>iterator</p>
</dd>
</dl>
</dd></dl>
<dl class="function">
<dt id="joy.utils.stack.list_to_stack">
<code class="descclassname">joy.utils.stack.</code><code class="descname">list_to_stack</code><span class="sig-paren">(</span><em>el</em>, <em>stack=()</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#list_to_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.list_to_stack" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.utils.stack.list_to_stack">
<span class="sig-prename descclassname"><span class="pre">joy.utils.stack.</span></span><span class="sig-name descname"><span class="pre">list_to_stack</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">el</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">stack</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">()</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#list_to_stack"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.stack.list_to_stack" title="Permalink to this definition"></a></dt>
<dd><p>Convert a Python list (or other sequence) to a Joy stack:</p>
<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">3</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">())))</span>
</pre></div>
</div>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>el</strong> (<em>list</em>) A Python list or other sequence (iterators and generators
wont work because <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> is called on <code class="docutils literal notranslate"><span class="pre">el</span></code>.)</li>
<li><strong>stack</strong> (<em>stack</em>) A stack, optional, defaults to the empty stack.</li>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>el</strong> (<em>list</em>) A Python list or other sequence (iterators and generators
wont work because <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> is called on <code class="docutils literal notranslate"><span class="pre">el</span></code>.)</p></li>
<li><p><strong>stack</strong> (<em>stack</em>) A stack, optional, defaults to the empty stack.</p></li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">stack</p>
</td>
</tr>
</tbody>
</table>
</dd>
<dt class="field-even">Return type</dt>
<dd class="field-even"><p>stack</p>
</dd>
</dl>
</dd></dl>
<dl class="function">
<dt id="joy.utils.stack.pick">
<code class="descclassname">joy.utils.stack.</code><code class="descname">pick</code><span class="sig-paren">(</span><em>stack</em>, <em>n</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#pick"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.pick" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.utils.stack.pick">
<span class="sig-prename descclassname"><span class="pre">joy.utils.stack.</span></span><span class="sig-name descname"><span class="pre">pick</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">stack</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">n</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#pick"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.stack.pick" title="Permalink to this definition"></a></dt>
<dd><p>Return the nth item on the stack.</p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>stack</strong> (<em>stack</em>) A stack.</li>
<li><strong>n</strong> (<em>int</em>) An index into the stack.</li>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>stack</strong> (<em>stack</em>) A stack.</p></li>
<li><p><strong>n</strong> (<em>int</em>) An index into the stack.</p></li>
</ul>
</td>
</tr>
<tr class="field-even field"><th class="field-name">Raises:</th><td class="field-body"><ul class="first simple">
<li><strong>ValueError</strong> if <code class="docutils literal notranslate"><span class="pre">n</span></code> is less than zero.</li>
<li><strong>IndexError</strong> if <code class="docutils literal notranslate"><span class="pre">n</span></code> is equal to or greater than the length of <code class="docutils literal notranslate"><span class="pre">stack</span></code>.</li>
</dd>
<dt class="field-even">Raises</dt>
<dd class="field-even"><ul class="simple">
<li><p><strong>ValueError</strong> if <code class="docutils literal notranslate"><span class="pre">n</span></code> is less than zero.</p></li>
<li><p><strong>IndexError</strong> if <code class="docutils literal notranslate"><span class="pre">n</span></code> is equal to or greater than the length of <code class="docutils literal notranslate"><span class="pre">stack</span></code>.</p></li>
</ul>
</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">whatever</p>
</td>
</tr>
</tbody>
</table>
</dd>
<dt class="field-odd">Return type</dt>
<dd class="field-odd"><p>whatever</p>
</dd>
</dl>
</dd></dl>
<dl class="function">
<dt id="joy.utils.stack.stack_to_string">
<code class="descclassname">joy.utils.stack.</code><code class="descname">stack_to_string</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#stack_to_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.stack_to_string" title="Permalink to this definition"></a></dt>
<dl class="py function">
<dt class="sig sig-object py" id="joy.utils.stack.stack_to_string">
<span class="sig-prename descclassname"><span class="pre">joy.utils.stack.</span></span><span class="sig-name descname"><span class="pre">stack_to_string</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">stack</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#stack_to_string"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#joy.utils.stack.stack_to_string" title="Permalink to this definition"></a></dt>
<dd><p>Return a “pretty print” string for a stack.</p>
<p>The items are written right-to-left:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">top</span><span class="p">,</span> <span class="p">(</span><span class="n">second</span><span class="p">,</span> <span class="o">...</span><span class="p">))</span> <span class="o">-&gt;</span> <span class="s1">&#39;... second top&#39;</span>
</pre></div>
</div>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>stack</strong> (<em>stack</em>) A stack.</td>
</tr>
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">str</td>
</tr>
</tbody>
</table>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>stack</strong> (<em>stack</em>) A stack.</p>
</dd>
<dt class="field-even">Return type</dt>
<dd class="field-even"><p>str</p>
</dd>
</dl>
</dd></dl>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Stack or Quote or Sequence or List…</a><ul>
<li><a class="reference internal" href="#module-joy.utils.stack"><code class="docutils literal notranslate"><span class="pre">joy.utils.stack</span></code></a></li>
<h1 class="logo"><a href="index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Stack or Quote or Sequence or List…</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#module-joy.utils.stack"><code class="docutils literal notranslate"><span class="pre">joy.utils.stack</span></code></a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -238,25 +252,24 @@ wont work because <code class="docutils literal notranslate"><span class="pre
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/stack.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -267,7 +280,7 @@ wont work because <code class="docutils literal notranslate"><span class="pre
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -1,19 +1,18 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Type Inference of Joy Expressions &#8212; Thun 0.4.1 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Essays about Programming in Joy" href="notebooks/index.html" />
@ -30,9 +29,11 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="type-inference-of-joy-expressions">
<section id="type-inference-of-joy-expressions">
<h1>Type Inference of Joy Expressions<a class="headerlink" href="#type-inference-of-joy-expressions" title="Permalink to this headline"></a></h1>
<p>UPDATE: May 2020 - I removed the type inference code in <cite>joy.utils.types</cite>
but you can find it in the <cite>v0.4.0</cite> tag here:
@ -44,7 +45,7 @@ functions, and a more complex inferencer/interpreter hybrid that can
infer the stack effects of most Joy expressions, including multiple stack
effects, unbounded sequences of values, and combinators (if enough
information is available.)</p>
<div class="section" id="joy-utils-types">
<section id="joy-utils-types">
<h2><code class="docutils literal notranslate"><span class="pre">joy.utils.types</span></code><a class="headerlink" href="#joy-utils-types" title="Permalink to this headline"></a></h2>
<p>Curently (asterix after name indicates a function that can be
auto-compiled to Python):</p>
@ -173,22 +174,41 @@ far.</p>
(i2 i1 -- i3)
</pre></div>
</div>
</div>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Type Inference of Joy Expressions</a><ul>
<li><a class="reference internal" href="#joy-utils-types"><code class="docutils literal notranslate"><span class="pre">joy.utils.types</span></code></a></li>
<h1 class="logo"><a href="index.html">Thun</a></h1>
<h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Type Inference of Joy Expressions</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#joy-utils-types"><code class="docutils literal notranslate"><span class="pre">joy.utils.types</span></code></a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -198,25 +218,24 @@ far.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/types.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
<script>$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
@ -227,7 +246,7 @@ far.</p>
</a>
<br />
<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>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.3.0.
</div>
</body>

View File

@ -76,7 +76,7 @@ E.g.:
Implementation
--------------
.. code:: ipython2
.. code:: python
from functools import partial as curry
from itertools import product
@ -533,10 +533,10 @@ machine transition table.
Says, “Three or more 1s and not ending in 01 nor composed of all 1s.”
.. figure:: attachment:omg.svg
:alt: omg.svg
.. figure:: omg.svg
:alt: State Machine Graph
omg.svg
State Machine Graph
Start at ``a`` and follow the transition arrows according to their
labels. Accepting states have a double outline. (Graphic generated with