Quadratic formula¶
-from notebook_preamble import J, V, define
+ from notebook_preamble import J, V, define
+
+Quadratic formula¶
--b +/- sqrt(b^2 - 4 * a * c)
------------------------------
- 2 * a
+ -b ± sqrt(b^2 - 4 * a * c)
+--------------------------------
+ 2 * a
\(\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\)
Write a straightforward program with variable names.¶
-b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
+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
-We use cleave to compute the sum and difference and then app2 to
-finish computing both roots using a quoted program [2a truediv]
-built with cons.
-
-Check it.¶
-Evaluating by hand:
- b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
--b b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
--b b^2 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
--b b^2 4ac - sqrt [+] [-] cleave a 2 * [truediv] cons app2
--b b^2-4ac sqrt [+] [-] cleave a 2 * [truediv] cons app2
--b sqrt(b^2-4ac) [+] [-] cleave a 2 * [truediv] cons app2
-
--b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) a 2 * [truediv] cons app2
--b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) 2a [truediv] cons app2
--b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] app2
--b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
+
+
+sqrt(b^2 - 4 * a * c)¶
+b sqr 4 a c * * - sqrt
-(Eventually we’ll be able to use e.g. Sympy versions of the Joy commands
-to do this sort of thing symbolically. This is part of what is meant by
-a “categorical” language.)
-
-Cleanup¶
--b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a roll< pop
- -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a -b pop
- -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
+
+/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.¶
-b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
-b [neg] dupdip sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
-b a c [[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
-b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop
-b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop
+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
-define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop')
+The three arguments are to the left, so we can “chop off” everything to
+the right and say it’s the definition of the quadratic function:
+define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
+Let’s try it out:
J('3 1 1 quadratic')
-0.3819660112501051 -2.618033988749895
-
-
-Simplify¶
-We can define a pm plus-or-minus function:
-pm == [+] [-] cleave popdd
+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.
+V('-5 1 4 quadratic')
-Then quadratic becomes:
-define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2')
+ . -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 .
-J('3 1 1 quadratic')
-
-
--0.3819660112501051 -2.618033988749895
-
-
-
-Define a “native” pm function.¶
-The definition of pm above is pretty elegant, but the implementation
-takes a lot of steps relative to what it’s accomplishing. Since we are
-likely to use pm more than once in the future, let’s write a
-primitive in Python and add it to the dictionary. (This has been done
-already.)
-def pm(stack):
- a, (b, stack) = stack
- p, m, = b + a, b - a
- return m, (p, stack)
-
-
-The resulting trace is short enough to fit on a page.
-V('3 1 1 quadratic')
-
-
- . 3 1 1 quadratic
- 3 . 1 1 quadratic
- 3 1 . 1 quadratic
- 3 1 1 . quadratic
- 3 1 1 . over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2
- 3 1 1 1 . [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2
- 3 1 1 1 [[[neg] dupdip sqr 4] dipd * * - sqrt pm] . dip 2 * [truediv] cons app2
- 3 1 1 . [[neg] dupdip sqr 4] dipd * * - sqrt pm 1 2 * [truediv] cons app2
- 3 1 1 [[neg] dupdip sqr 4] . dipd * * - sqrt pm 1 2 * [truediv] cons app2
- 3 . [neg] dupdip sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- 3 [neg] . dupdip sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- 3 . neg 3 sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 . 3 sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 3 . sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 3 . dup mul 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 3 3 . mul 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 . 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 . 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 1 . 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 1 1 . * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 1 . * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 . - sqrt pm 1 2 * [truediv] cons app2
- -3 5 . sqrt pm 1 2 * [truediv] cons app2
- -3 2.23606797749979 . pm 1 2 * [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 . 1 2 * [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 1 . 2 * [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 1 2 . * [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 2 . [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 2 [truediv] . cons app2
- -0.7639320225002102 -5.23606797749979 [2 truediv] . app2
- [-0.7639320225002102] [2 truediv] . infra first [-5.23606797749979] [2 truediv] infra first
- -0.7639320225002102 . 2 truediv [] swaack first [-5.23606797749979] [2 truediv] infra first
- -0.7639320225002102 2 . truediv [] swaack first [-5.23606797749979] [2 truediv] infra first
- -0.3819660112501051 . [] swaack first [-5.23606797749979] [2 truediv] infra first
- -0.3819660112501051 [] . swaack first [-5.23606797749979] [2 truediv] infra first
- [-0.3819660112501051] . first [-5.23606797749979] [2 truediv] infra first
- -0.3819660112501051 . [-5.23606797749979] [2 truediv] infra first
- -0.3819660112501051 [-5.23606797749979] . [2 truediv] infra first
--0.3819660112501051 [-5.23606797749979] [2 truediv] . infra first
- -5.23606797749979 . 2 truediv [-0.3819660112501051] swaack first
- -5.23606797749979 2 . truediv [-0.3819660112501051] swaack first
- -2.618033988749895 . [-0.3819660112501051] swaack first
- -2.618033988749895 [-0.3819660112501051] . swaack first
- -0.3819660112501051 [-2.618033988749895] . first
- -0.3819660112501051 -2.618033988749895 .
-
-
-
@@ -195,15 +175,14 @@ already.)
@@ -212,8 +191,8 @@ already.)
- Documentation overview
- Essays about Programming in Joy
- - Previous: Newton’s method
- - Next: Traversing Datastructures with Zippers
+ - Previous: Developing a Program in Joy
+ - Next: Replacing Functions in the Dictionary
diff --git a/docs/sphinx_docs/_build/html/notebooks/Zipper.html b/docs/sphinx_docs/_build/html/notebooks/Zipper.html
index d424e17..22d2d17 100644
--- a/docs/sphinx_docs/_build/html/notebooks/Zipper.html
+++ b/docs/sphinx_docs/_build/html/notebooks/Zipper.html
@@ -16,8 +16,8 @@
-
-
+
+
@@ -326,8 +326,8 @@ i d i d i d d Bingo!
- Documentation overview
- Essays about Programming in Joy
- - Previous: Quadratic formula
- - Next: No Updates
+ - Previous: Newton’s method
+ - Next: Type Inference
diff --git a/docs/sphinx_docs/_build/html/notebooks/index.html b/docs/sphinx_docs/_build/html/notebooks/index.html
index f5213e5..4c74e30 100644
--- a/docs/sphinx_docs/_build/html/notebooks/index.html
+++ b/docs/sphinx_docs/_build/html/notebooks/index.html
@@ -44,12 +44,32 @@
- The Simplest Program
+- Quadratic formula
+
- Replacing Functions in the Dictionary
+- Recursive Combinators
+
- Treating Trees I: Ordered Binary Trees
-- Quadratic formula
-
- Traversing Datastructures with Zippers
- Trees
- Zipper in Joy
@@ -104,6 +118,20 @@
- Determining the right “path” for an item in a tree.
+- Type Inference
+
- No Updates
- Categorical Programming
diff --git a/docs/sphinx_docs/_build/html/objects.inv b/docs/sphinx_docs/_build/html/objects.inv
index d60701a094cb7f3493d67fb6fdacfbd4c250f078..fad1ba971ab12a8dbc9853eb7a5d441d96f9405e 100644
GIT binary patch
delta 1222
zcmV;%1UdVH3atu|cYjNA8#fT$^AxCxmnI`QJ1uR=E~WC3^+~F-VS$(?2?+zh_=p^@
ze2rWn2lGkN7|d`$X=tgX6^H2eUIX2Y24-$eGrKhnv&~6us;Gb+G5kMUhg$uVN2YJs
zbaI<;k_*S({tUaZ(OLGk_kU93&-*A-)M*XYxEO#CXMWW!xE|f2b?v<>q
zf>#LKye_*bl3Ypd!INm#9ux8Ji1=S9_yq~E1q(q3?&PjNq1rJn8
zMZ}YeqLP*fuYag`BHHTA-%@}2w#-~ih&4`vQqZ2aDLZ@R@|#<(#^<4G}O88Vde<-^E9@`M6jx!rthi$1|q(ueGmOnN9@#ySc48c`Ac&vDg6gH_A8E`r)o)+0d9gD
zzQp0*jO#z*c=pMeXz^mTXx=h#Z+8~9kzviwwmg0F@ss|G-oDtbnGCc`Sb_sBV1iXP
z5`O~QOnXCS{+H`^*>dd%q
zYZ~h1q%8uR``5GFc}h)lV=J8Tfi>^U
zoswbQ|3czVS7F6e^ZfC5e(m6p+8DB1xC7i67{<KVcn~Wo#ZVoPLhH!bnRo?rCSv
z@&kHlTpblJlrBL;*EYWore2^o%(RqT$A5|l
zYhb6c{f{vz)Z6H!tMI6JZygUc#yWI>Qn9gzve=qBEquhC-*=1w^N(yl4v+G)t)C1}
zuV869r#x`%%u$4hr%`TS8Cu5iQMY|y%CcwP^Tsp2Ffo+9q~HAAm8p;^E+Z`6joJX=
z4F(ywuhWh^+nthrlF#iu{&13~ML)H<%PcI6w&i=^POSHvX&%e0t8BmEE12Z-u#g{4
kCwA4^@ZR=0;?mQ@72tImnSkP9wWt0Z$74SGVb(8vFvuH7YziiMA#s};Kvek
z%4_rm@?d$AE(lVDY&!PZCsEk%`+!|6c0t~lW_Dv5RySvrDS`ra!tnpB^p*N4jZA-L
z)5%T3_1I0&!b_vs>445*7Hah@T+mO!lw4bGk5|}@jjpn{y?>V)f8GbFywv|#Ue{pn
z&2=PmpFf9<)G{J7vQXSPGIPd@VpYKApiqG?P4Qx#Zq&V6ujbZ4rbrb0(1r2^(Ot@_
zR`3de>(}jWj3if*J8&dgU7r&1?}+$cDEKuAY`GRCg&|5K1&|mDIB6q9Rj){RqXqXw
zMnS}ra-xtm5r1A#@kGKMmPAre3u|aT1S-6s;%PzMNb5*Ru~Ej5@^lN@f}kNfdWBt#g*Jj
zy`@otrp;ljC!HYo+0rKPT-?%T@IVV}5Q2uUXzST=bb-hqdEogiDPg^=Xt!-2XbvEZ
zcy|k0ehxrmw5dU%+!;x#Hal+drtTXO$Jm18`JMv)BA?d}+rDFuUe(jk=$m?HTEw4o
zYtwxU_J0EEZjPLLkF;#6wNd#i`47Mz_I~Bf3iep|o$Fq7GiS!Q!As?0r|`a6)mYK|
zv0trW)USuk*_Gu27V+`;J3_AVO!{nV+J*FQ=r57Dld$Xd>1mlmz8`#VM}FXXvJcUY
zv3Gu?DP%%p3V40CtFhzu1W!rl)0|{#Ey;}F%6~O^p44BS85ex_kh*|9ju&T&uR*ct
zDeFgD9J`2*lL1y35kVQ^3Y#oDnZ28xu(=VT0_}O6FRm@8^k3lEZ#aGt^Cjj6*a;r_
z9EX1suK$YT*hgzZjaRF6^M-+abFi?T^d&pr^Z3!nP5MuI$6|+aGSDtz0~WM^3Fg^I
z2!HBk+8Yw{kCdV*7}|JP8*}U4{>nXUjg^9{e9}=s63Q71YqpkGcxm5ensdCdDO1PI
z8dL}nYGcUGaSM1bFpPNergRCl;^NVqI+&BvfF6z@?v*cr&1L%^SDUG~>yFpdQSsh79t4bn?|%T9
z;=i)}@H(oOY`q$f?>A9z&OOJX7laSk9#UmU&^)9M3fVnVl0A2hH;(bO2|hoj{kiJy
zBbiLr=~=vZv>xL102z2>VzQqf+LoK7rg+33+GKR94Sr&Q2yHcWz^y2c>r@&`tYxw<
t_!cIqL1pqo;b+U%hL@sG0bP#|OBBGnDi*`|{5!U|?_a-7{s)nsGa`P>TQ~p!
diff --git a/docs/sphinx_docs/_build/html/searchindex.js b/docs/sphinx_docs/_build/html/searchindex.js
index 2d59585..5ea0dfc 100644
--- a/docs/sphinx_docs/_build/html/searchindex.js
+++ b/docs/sphinx_docs/_build/html/searchindex.js
@@ -1 +1 @@
-Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Replacing","notebooks/Treestep","notebooks/Zipper","notebooks/index","parser","pretty","stack"],envversion:52,filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Replacing.rst","notebooks/Treestep.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst"],objects:{"joy.joy":{joy:[1,1,1,""],repl:[1,1,1,""],run:[1,1,1,""]},"joy.library":{"void":[3,1,1,""],BinaryBuiltinWrapper:[3,1,1,""],DefinitionWrapper:[3,2,1,""],FunctionWrapper:[3,1,1,""],SimpleFunctionWrapper:[3,1,1,""],UnaryBuiltinWrapper:[3,1,1,""],add_aliases:[3,1,1,""],app1:[3,1,1,""],app2:[3,1,1,""],app3:[3,1,1,""],b:[3,1,1,""],branch:[3,1,1,""],choice:[3,1,1,""],clear:[3,1,1,""],cmp_:[3,1,1,""],concat:[3,1,1,""],cond:[3,1,1,""],cons:[3,1,1,""],dip:[3,1,1,""],dipd:[3,1,1,""],dipdd:[3,1,1,""],divmod_:[3,1,1,""],drop:[3,1,1,""],dup:[3,1,1,""],dupd:[3,1,1,""],dupdip:[3,1,1,""],first:[3,1,1,""],floor:[3,1,1,""],genrec:[3,1,1,""],getitem:[3,1,1,""],help_:[3,1,1,""],i:[3,1,1,""],id_:[3,1,1,""],ifte:[3,1,1,""],infra:[3,1,1,""],initialize:[3,1,1,""],inscribe:[3,1,1,""],loop:[3,1,1,""],map_:[3,1,1,""],max_:[3,1,1,""],min_:[3,1,1,""],over:[3,1,1,""],parse:[3,1,1,""],pm:[3,1,1,""],pop:[3,1,1,""],popd:[3,1,1,""],popdd:[3,1,1,""],popop:[3,1,1,""],pred:[3,1,1,""],remove:[3,1,1,""],rest:[3,1,1,""],reverse:[3,1,1,""],rolldown:[3,1,1,""],rollup:[3,1,1,""],select:[3,1,1,""],sharing:[3,1,1,""],shunt:[3,1,1,""],sort_:[3,1,1,""],sqrt:[3,1,1,""],stack_:[3,1,1,""],step:[3,1,1,""],succ:[3,1,1,""],sum_:[3,1,1,""],swaack:[3,1,1,""],swap:[3,1,1,""],take:[3,1,1,""],times:[3,1,1,""],tuck:[3,1,1,""],uncons:[3,1,1,""],unique:[3,1,1,""],unstack:[3,1,1,""],warranty:[3,1,1,""],words:[3,1,1,""],x:[3,1,1,""],zip_:[3,1,1,""]},"joy.library.DefinitionWrapper":{add_def:[3,3,1,""],add_definitions:[3,3,1,""],parse_definition:[3,3,1,""]},"joy.parser":{ParseError:[16,4,1,""],Symbol:[16,2,1,""],text_to_expression:[16,1,1,""]},"joy.utils":{pretty_print:[17,0,0,"-"],stack:[18,0,0,"-"]},"joy.utils.pretty_print":{TracePrinter:[17,2,1,""]},"joy.utils.pretty_print.TracePrinter":{go:[17,5,1,""],viewer:[17,5,1,""]},"joy.utils.stack":{expression_to_string:[18,1,1,""],iter_stack:[18,1,1,""],list_to_stack:[18,1,1,""],pick:[18,1,1,""],pushback:[18,1,1,""],stack_to_string:[18,1,1,""]},joy:{joy:[1,0,0,"-"],library:[3,0,0,"-"],parser:[16,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","classmethod","Python class method"],"4":["py","exception","Python exception"],"5":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:classmethod","4":"py:exception","5":"py:method"},terms:{"0b11100111011011":5,"4ac":11,"5bkei":10,"\u03b5":8,"abstract":[7,10],"boolean":[2,3,7,10],"break":7,"byte":5,"case":[2,3,13,18],"class":[3,7,16,17,18],"default":[3,6,10,18],"export":[3,16],"final":[2,10],"float":[3,7,14,16],"function":[0,1,4,5,6,9,14,15,16,17,18],"g\u00e9rard":14,"import":[2,5,6,8,10,11,12,13,14],"int":[6,7,14,16,18],"long":[10,15],"new":[2,3,6,7,9,12],"public":9,"return":[1,3,5,7,10,11,12,13,16,17,18],"short":11,"static":[2,9],"switch":2,"throw":10,"true":[2,3,5],"try":[6,8,13],"void":[0,3],"while":[3,7,10,16,18],Adding:[7,12,15],And:[5,6,8,10,14,18],But:[0,4,5,6,7,10,12],CPS:7,For:[2,3,10,12,15,18],Has:3,Its:3,One:[2,7,15],TOS:[2,3],That:[5,10],The:[0,1,2,3,4,6,8,9,11,14,15,16,18],Then:[2,3,10,11],There:[13,18],These:[15,18],Use:[3,8],Using:[0,8,10,15],With:[8,15],__str__:17,_tree_add_:10,_tree_add_e:10,_tree_add_p:10,_tree_add_r:10,_tree_add_t:10,_tree_delete_:10,_tree_delete_clear_stuff:10,_tree_delete_del:10,_tree_delete_r0:10,_tree_delete_r1:10,_tree_delete_rightmost:10,_tree_delete_w:10,_tree_get_:10,_tree_get_p:10,_tree_get_r:10,_tree_get_t:10,_tree_iter_order_curr:10,_tree_iter_order_left:10,_tree_iter_order_r:10,_tree_iter_order_right:10,_tree_t:10,_treestep_0:13,_treestep_1:13,_within_b:8,_within_p:8,_within_r:8,abbrevi:13,abl:11,about:[0,7,10,14,18],abov:[0,5,8,10,11],abs:8,absolut:7,accept:[1,2,3,5,6,7,10,12,13,14],accomplish:11,accordingli:10,accumul:5,action:[7,12,14],actual:[2,5,7,10],adapt:15,add:[3,5,6,7,11,12,17],add_alias:3,add_def:3,add_definit:[3,10,13],added:[4,10],adding:9,addit:[0,2,3,5,7,12,13],address:15,adjust:10,after:[5,6,7],afterward:7,again:[2,3,5,7,10],aggreg:[3,14],aka:[7,14],albrecht:0,algorithm:7,alia:3,alias:[3,7],align:[7,17],all:[3,5,6,7,10,12,13,17],allow:[9,10],almost:10,along:7,alphabet:3,alreadi:[8,11,12,14],also:[0,5,7,10,18],altern:4,although:[4,10],altogeth:6,alwai:[5,9],amort:10,analysi:[4,15],anamorph:7,ani:[4,5,7,9,10,14,16],annual:7,anonym:10,anoth:[10,18],anyth:[2,3,7],api:9,app1:3,app2:[3,7,11,12],app3:3,app:7,appear:[2,4,5,10],appendix:15,appli:[2,3,5,6,10],applic:6,approach:5,approxim:15,archiv:0,aren:14,arg:[2,3],argument:[2,3,7,8,17,18],arithmet:2,ariti:2,around:[5,18],arrang:13,arriv:[6,13],articl:[0,4,6],ask:[4,6],aspect:0,assign:18,associ:10,assum:8,asterisk:13,attack:7,attempt:[0,1],attribut:3,automat:4,auxiliari:13,avail:0,averag:[7,12],avoid:10,awai:10,awar:2,awkward:10,azur:15,back:10,backward:[9,10,13],bag:7,base:[0,2,3,9,13],basic:[1,2,3,7,10],becaus:[2,3,7,10,13,14,18],becom:[10,11,13,18],been:[8,9,10,11,14],befor:[6,7,10],begin:[10,13],behavior:[9,13],behaviour:[0,1],being:0,below:[2,3,5,6,10,14],bespok:7,best:0,better:[5,10],between:[0,5],beyond:6,biannual:7,binari:[0,6,7,15],binary_search_tre:10,binarybuiltinwrapp:3,bind:7,bingo:14,bit:[5,6,10],block:5,bodi:[2,7,10],body_text:3,borrow:7,both:[2,5,7,11,12,18],bottom:6,bracket:[7,16],branch:[3,5,6],breakpoint:7,bring:[5,7],btree:[10,13],buck:10,bug:[0,7],build:[6,7,14,18],built:11,bundl:[2,3],burgeon:7,calculu:4,call:[2,7,9,10,17,18],caller:10,can:[0,2,3,4,5,6,7,8,9,11,12,13,14,15,18],captur:7,card:7,care:[5,18],carefulli:14,carri:[6,10],cartesian:4,categor:[0,11,15],categori:4,ccc:4,ccon:10,certain:[7,18],certainli:10,chain:3,chang:[2,9,10,14],charact:14,chat:7,chatter:0,check:[6,8],child:13,choic:3,choos:9,cinf:10,circuit:4,cite_not:10,classmethod:3,claus:3,clear:[3,5,7],clear_stuff:10,cleav:[7,11,12],close:[0,1,4],clunki:5,cmp:[3,13,15],cmp_:3,code:[0,1,4,15],codireco:[6,8],collect:[4,6,7],combin:[0,3,5,6,7,8,13,14,15],come:[7,10],command:[7,10,11],common:[2,5],compar:[3,4],comparison:[0,10],compel:4,compil:[2,4,7,10,12,15],complet:4,complex:[3,14],compound:10,comput:[2,4,5,7,11],con:[3,5,6,7,8,10,11,13,14,18],conal:4,concat:[3,6,7,13],concaten:0,concatin:[0,3,18],concurr:2,cond:[3,10],condit:[3,7],conflict:10,consecut:15,consid:[5,6,10,13,14],consist:[2,6,7,13],constant:10,contain:[0,2,3,6,7],context:2,conting:10,continu:[0,14],control:7,conveni:4,convert:[12,13,16,18],cool:10,copi:[2,3,5,10,13,15],copyright:7,correspond:4,could:[2,4,5,7,9,10,14],count:3,counter:5,coupl:13,cours:[5,10],crack:10,crash:10,creat:[0,2,3,5,8,10],crude:[10,16],current:[2,3,7,13,14,17],custom:9,cycl:[5,6],cython:7,dai:7,data:[2,3],datastructur:[0,2,15,16,18],datatyp:18,ddididi:14,deal:[0,10],decid:10,decor:3,decrement:3,deduc:5,deeper:0,deepli:4,def:[3,7,11,12,18],defi:3,defin:[2,3,4,5,6,7,8,9,12,14,15],definit:[2,3,5,6,7,9,10,13,15],definitionwrapp:[3,10,13],deleg:7,delet:15,demonstr:4,depend:[3,10],deposit:13,der:10,deriv:[2,3,5,7,8,10,15],describ:[3,4,10,13,16],descript:[5,7],design:[2,3,10],desir:[7,13],destruct:10,detail:[7,10],detect:[6,10],determin:15,develop:[0,6,7,15],diagram:5,dialect:1,dict:[1,3],dictionari:[0,1,3,7,11,15],differ:[0,4,5,8,10,11,18],differenti:4,dig:[10,14],digit:5,dinfrirst:7,dip:[3,5,6,7,8,10,11,12,13,15],dipd:[3,6,7,10,11,14],dipdd:[3,10],direco:15,direct:7,directli:[5,13,18],disappear:2,discard:[3,6,8,10],disciplin:10,disenstacken:7,disk:7,displac:2,ditch:10,div:[3,7],dive:13,divis:10,divmod:3,divmod_:3,doc:[2,3,7],document:[15,16,18],doe:[0,1,4,6,7,12,15,17],doesn:[5,9,10,13,18],doing:[4,5,7,14],domain:4,don:[5,7,10],done:[2,5,7,9,11],door:7,dot:17,doubl:[5,7],down:[2,3,8,14],down_to_zero:7,dozen:7,draft:[4,9],dream:7,drive:[6,8],driven:5,driver:6,drop:[3,10],dudipd:7,dup:[3,5,6,7,8,10,11,14,18],dupd:3,dupdip:[3,5,10,11],duplic:[3,10],durat:2,dure:2,each:[2,3,4,5,7,12,13,17],easi:[0,10,13,14],easier:[3,10],easili:4,edit:15,effect:[2,3,7,14],effici:[6,12,14],either:[1,2,3,10],eleg:[7,10,11],element:[2,3],elliott:4,els:[2,3],embed:[4,10,14],empti:[3,7,13,18],encapsul:7,enclos:7,encod:6,end:[5,10,13,18],endless:6,enforc:[2,7],engend:7,enough:[7,11,17],enstacken:[6,7],enter:7,entir:18,entri:[3,14,17],epsilon:8,equal:[5,13,18],equat:[7,8],ergo:10,err:10,error:[7,16],essai:0,etc:[3,13,14,16],euler:15,eval:0,evalu:[1,2,3,7,8,10,11,12,13],eventu:11,everi:6,everyth:[3,10],evolv:9,exampl:[0,3,5,15,16,18],exce:6,except:[7,10,16],execut:[0,1,2,3,7,12,13,14,18],exercis:10,exist:[4,10],expand:10,expect:[2,3,13,18],experi:[7,13],explan:7,explor:7,express:[0,1,2,3,4,10,12,14,17,18],expression_to_str:18,extra:[5,6],extract:[10,15],extrem:7,extrememli:7,facet:0,facil:7,fact:16,factor:[2,5,7,10],fail:[2,3,10,16],fals:[2,3,5],far:[8,10],fascin:0,fear:10,few:[5,7,8],fewer:[3,7],fib:6,fib_gen:6,fibonacci:15,figur:[2,3,10],filter:10,fin:5,find:[2,3,5,6,13,15],finder:8,fine:[0,5,10],finish:11,first:[3,6,7,8,10,11,12,13,14,15],first_two:10,fit:[5,7,11],five:[5,7,15],fix:[2,3],flatten:[7,13],flexibl:15,floor:3,floordiv:5,flow:7,follow:[0,2,3,7,9,13,14],foo:[7,9,10],foo_ii:9,form:[2,3,4,5,6,13,18],forman:7,format:[15,17],formula:[0,5,15],forth:7,forum:0,found:7,four:[2,3,5,6,7,10],fourteen:5,fourth:[2,3,10],fractal:7,fraction0:7,fraction:[2,7],framework:7,free:[4,7,10],freeli:2,from:[0,1,2,3,5,6,7,8,10,11,12,13,14,15,18],front:[2,3],full:5,functionwrapp:3,funtion:10,further:[8,15],futur:11,garbag:7,gari:10,gcd:7,gener:[0,2,3,4,15,18],genrec:[3,7,10,13],geometr:5,get:[2,4,5,6,7,15],getitem:3,getrecursionlimit:18,getsourc:7,ghc:4,give:[4,5,10,13,18],given:[2,3,5,6,8,10,14,15],glue:7,going:[10,13,14],good:[5,10],grab:3,grammar:16,grand:7,great:[0,7,15],greater:18,group:0,gsra:8,guard:10,had:[5,14],haiku:7,half:[5,14],hand:[7,11,12,15],handi:8,handl:[10,18],happen:7,hard:14,hardwar:4,has:[0,2,6,7,8,9,10,11,14,18],haskel:4,have:[2,3,5,6,7,8,9,12,14,15,18],head:18,help:[7,10],help_:3,helper:3,herd:7,here:[5,6,10,13,14],hide:10,higher:[7,10],highli:7,histori:17,hmm:10,hoist:3,hold:5,hood:10,hope:[0,5,7,15],host:15,how:[0,4,8,10,14,15],howev:12,html:[2,3,6,11,15],http:10,huet:14,huge:10,hugh:[8,13],human:7,hypothet:2,id_:3,idea:[4,5,7],ident:3,if_not_empti:10,ift:[3,10,13],ignor:[3,10],imagin:14,imit:13,immut:[7,10],implement:[0,1,2,3,4,7,9,10,11,12],implicit:7,includ:[4,10,13],inclus:5,incom:18,incompat:9,increas:5,increment:[3,4,5,9],index:[0,7,18],indexerror:18,indic:13,inform:3,infra:[3,6,7,10,11,12,13,15],infrastructur:3,initi:[2,3,7,8,10],inlin:10,input:[1,8],inscrib:3,inspect:7,instal:0,instanti:[4,17],instead:[5,6,10,14,18],integ:[2,3,7,13],integr:3,intend:[0,7],interact:[7,15],interest:[0,5,10,15],interlud:15,intern:[0,17,18],interpret:[0,4,9,12,16,17],interrupt:7,interv:[4,5],introduc:9,introduct:0,invari:3,invers:3,ipf:7,isn:[10,14],item:[2,3,7,10,13,15,18],iter:[1,3,7,13,15,18],iter_stack:[12,18],its:[0,2,3,4,5,7,10,13,18],itself:[0,2,7,10],j05cmp:[2,3],job:15,john:[8,13],joi:[2,4,9,10,11,12],joypi:[7,14],jupyt:15,just:[0,2,3,6,7,9,10,13,14],keep:[10,14],kei:[13,15],kevin:0,key_n:10,keyerror:10,kind:[2,4,7,10,13],kleen:13,know:[5,10],known:4,l_kei:10,l_left:10,l_right:10,l_valu:10,lambda:4,languag:[4,7,9,10,11,12],larger:18,largest:3,last:[5,10],lastli:6,later:[7,13],law:2,lazili:8,lcm:5,lead:7,leaf:10,lean:7,learn:0,least:[2,5,18],least_fract:7,leav:5,left:[7,13,14,17,18],length:[3,5,18],less:[5,6,7,18],let:[6,8,10,11,13,14],level:[4,10],librari:[0,12],like:[2,3,5,7,11,13,15,16],line:[3,7,10,17],linear:18,link:0,linux:0,list:[0,3,5,7,8,10,13,14,17],list_to_stack:18,liter:[1,10,13,14,16],littl:[6,10,15],live:15,lkei:13,load:[5,7],locat:2,locu:17,log_2:10,logic:[0,5],longer:10,look:[6,7,8,10],lookup:7,loop:[0,1,3,5],lot:[7,10,11,14],love:5,low:4,lower:5,lowest:10,machin:0,machineri:10,macro:7,made:[0,7,14],mai:2,mail:0,main:[0,3,7,14],mainloop:9,maintain:14,major:9,make:[2,3,4,5,7,10,12,13,14,15],make_gener:8,manfr:[0,2,3,4],mani:[0,7],map:[1,3,5,7,9,13],map_:3,marker:7,mask:[5,6],match:[0,1],materi:0,math:[0,7,8,10],mathemat:7,matter:[5,8,10,13],max_:3,maximum:3,mayb:10,mean:[4,5,7,8,10,13,18],meant:[7,10,11,13],member:[2,3],mental:7,mention:2,mercuri:0,meta:[7,10,12],method:[0,3,7,15,17],midpoint:5,might:[4,6,10],mike:10,million:6,min_:3,minimum:3,minor:10,minu:[3,11],mirror:0,miscellan:0,mix:7,mod:3,model:[4,7],modern:0,modif:6,modifi:[7,10,14],modul:[0,1,3,7,16],modulu:7,month:7,more:[0,3,4,5,6,7,8,11,12,13,16,18],mostli:0,move:10,movement:2,much:[5,6,10],muck:10,mul:[7,11,14,17],multi:3,multipl:15,must:[2,3,5,9,13],name:[1,3,7,9,10,14,15,16,18],natur:[5,6,10],navig:14,neat:10,need:[2,3,5,6,8,9,10],neg:[3,11],nest:[3,7,10,14],network:7,never:9,new_kei:10,new_valu:10,newton:[0,15],next:[5,13],nice:[0,18],niether:2,node:[13,15],node_kei:10,node_valu:10,non:13,none:[1,3],nope:13,notat:[7,10],note:[2,5,8,10,18],notebook:[5,6,7,14,15],notebook_preambl:[2,5,6,8,10,11,12,13,14],noth:[2,10],notic:5,now:[5,6,7,12,13,15],nth:[3,18],nullari:[7,10],number:[1,2,3,5,6,8,18],object:16,observ:5,obviou:6,occur:10,odd:[5,6],off:[2,3,5,6,14],old:[2,12],old_k:10,old_kei:10,old_valu:10,onc:[3,9,10,11],one:[2,3,5,6,10,13,17,18],ones:6,onli:[2,3,5,10,14,18],onto:[1,2,3,7,18],open:7,oper:[3,7,10,18],optim:10,option:[1,7,10,18],order:[0,2,3,7,15,18],org:[0,10],origin:[0,1,2,3,10,14],other:[0,2,3,4,7,10,13,18],otherwis:[3,5,6,10,13],our:[5,6,7,8,13],out:[2,3,4,5,6,7,8,10,14],outcom:13,output:8,outsid:4,over:[3,4,5,6,7,8,10,11,13,15],own:10,pack:18,packag:[0,7],page:[0,10,11,18],pair:[2,3,5,6,10],palidrom:5,palindrom:5,pam:7,paper:[4,7,14],parallel:2,paramet:[1,2,3,12,16,17,18],parameter:15,parenthes:[10,18],pariti:6,pars:[0,3,7],parse_definit:3,parseerror:16,parser:0,part:[2,3,8,11,13],particular:14,pass:[0,10,17],path:15,pattern:[5,13],pe1:[5,6],pe2:6,pearl:14,pend:[3,7,14,17],peopl:15,per:[7,13],perhap:6,period:7,permit:18,persist:10,phase:2,pick:[5,6,18],pickl:7,pictur:10,pip:0,place:[3,5,7],plai:0,plu:[3,11],plug:[6,13],point:[4,7,10],pointless:2,pop:[3,5,6,7,10,11,12,13,18],popd:[3,7,8,10,12],popdd:[3,6,11],popop:[3,5,6,7,8,10,13],posit:[3,5,7],possibilit:10,possibl:[10,13,15],post:7,potenti:3,power:7,pragmat:5,preambl:8,precis:[0,1],pred:3,predic:[2,3,6],prefix:17,preserv:[4,13],pretti:[8,10,11,13,17,18],pretty_print:0,previou:7,prime:8,primit:[2,3,11],primrec:[3,6,7,8],print:[0,1,2,3,17,18],probabl:[6,7,10],problem:[7,15],proc_curr:10,proc_left:10,proc_right:10,proce:5,process:[7,13,17],produc:[5,10,13],product:[6,7],program:[0,2,3,6,7,8,10,14],project:15,prompt:7,proper:[2,3],properti:0,provid:[0,3,4,7],pun:[0,7],pure:0,puriti:7,purpos:7,push:[2,3,7,14,18],pushback:[7,18],put:[1,2,6,7,15,18],pypi:0,python:[0,2,3,10,11,14,15,16,18],quadrat:[0,15],queri:[10,13],query_kei:13,quit:[0,1,13],quot:[0,3,6,7,10,11,13,14,17],quotat:[2,3],quotient:3,r_kei:10,r_left:10,r_right:10,r_valu:10,rais:[10,16,18],rang:7,range_to_zero:7,raphson:8,rather:[5,7,13],ratio:7,reach:[5,6],read:[0,1,5,6,10,14],readabl:12,reader:10,real:10,realiz:[4,10],rearrang:[2,10],reason:[5,7],rebuild:[13,14],rec1:[2,3],rec2:[2,3],recogn:16,record:[7,17],recurs:[2,3,6,7,8,15,18],recus:7,redefin:15,redistribut:[3,7],reduc:2,redund:18,refactor:[7,9],refer:[0,2],regist:2,regular:16,reimplement:15,rel:11,releas:9,remain:[2,3,7,9],remaind:[3,8],remov:[3,10,18],render:15,repeat:5,repeatedli:5,repl:[0,1],replac:[0,2,3,6,13,14,15,18],repositori:0,repres:[2,7,10,16,17],represent:18,reprod:6,requir:18,resembl:7,respect:5,rest:[3,5,6,7,10,14,15,18],rest_two:10,restor:2,result:[1,2,3,5,10,11,13,14],resum:7,retir:2,retri:7,reus:10,revers:[3,5,6,14,18],rewrit:[3,7],rewritten:7,rid:10,right:[6,7,13,15,17,18],rightest:10,rightmost:5,rkei:13,roll:[3,8,10,11,13],rolldown:3,rollup:3,root:[3,8,11],run:[0,1,3,5,7,8,10,13,14],runtimeerror:18,sai:[6,10,13],same:[2,4,5,10,18],sandwich:[2,3],save:[2,5,7],scan:3,scanner:[7,16],scenario:14,scope:[6,10],search:[0,10],second:[3,7,10,13,18],see:[0,6,7,8,9,12,14,17],seem:[0,5,7,13],seen:14,select:3,semant:[2,3,7,9,10],semi:7,send:7,sens:[0,2,5,14],separ:7,sequenc:[0,1,2,3,5,7,10,12,14,15,16],seri:[5,6,10,14],set:[2,3,15],seven:[5,6],sever:[0,4,7],share:[3,7],shelf:2,shift:[5,6],shorter:15,shorthand:10,should:[2,3,5,10],shouldn:7,show:[4,14],shunt:[3,14],side:10,signifi:[7,10],similar:[10,13],simon:7,simpl:[7,18],simplefunctionwrapp:[3,12],simpler:13,simplest:15,simpli:4,simplifi:[5,10,14,15],sinc:[2,5,10,11],singl:[3,6,7,12,16],situ:10,situat:10,six:[5,6,7],sixti:[5,6],size:[7,15],skeptic:7,slight:8,slightli:10,smallest:3,smart:10,softwar:7,solei:2,solut:[5,6],solvabl:7,some:[2,3,6,7,10,13,15,18],somehow:10,someth:[2,9,10],sometim:10,somewher:[10,15],sort:[3,10,11],sort_:3,sourc:[0,1,3,15,16,17,18],space:[5,17],span:5,special:[6,10],specif:[0,4],specifi:10,speed:12,spell:13,sphinx:[15,18],spirit:[0,1,13],sqr:[7,8,11,14],sqrt:[3,8,11],squar:[3,8,16],stack:[0,1,3,5,6,8,10,11,12,13,14,16,17],stack_:3,stack_to_str:18,stage:13,stai:[0,1],stand:4,standard:[7,10],star:13,stare:10,start:[5,6,7,8,10,13],state:7,statement:3,step:[3,5,7,10,11,12,14,15],still:10,stop:10,storag:[5,10],store:5,str:[1,16,17,18],straightforward:[1,6,8,15],stream:5,stretch:10,string:[1,2,3,7,14,16,17,18],structur:[7,13,14,15,18],stuff:10,style:[0,4],sub:9,subclass:7,subject:14,substitut:10,subtract:5,succ:3,success:8,suffici:10,suggest:[4,10],suitabl:[3,4,5],sum:[3,6,7,11,12,13],sum_:3,summand:5,sumtre:13,suppli:[10,16],support:[7,17,18],suspect:2,swaack:[3,11,12,14],swap:[3,5,6,7,8,10,12,13,14],swon:[3,6,7,13,14],swoncat:[6,7,8,13],symbol:[2,3,11,14,16],symmetr:[5,10],sympi:11,syntact:7,syntax:[7,18],sys:18,system:[7,10],tail:[10,18],take:[3,5,7,8,10,11,18],talk:[7,10,18],target:14,tast:4,tbd:7,technic:2,techniqu:[4,14],technolog:2,temporari:14,ten:5,term:[1,2,7,8,15,16,18],termin:[2,3],ternari:7,test:[2,3],text:[0,1,3],text_to_express:[7,16],textual:7,than:[0,3,5,6,7,8,11,13,18],thei:[2,5,6,7,10,14,16,18],them:[2,3,5,6,10,14,15],theori:[2,3],therefor:6,thi:[0,1,2,3,4,5,6,7,8,11,13,14,15,16,17,18],thing:[2,6,10,11,14,16,18],think:[2,5,7,10,13],third:[3,6,7,10],thirti:5,those:[2,3,10,15],though:5,thought:7,thousand:5,thread:2,three:[2,3,5,7,10,13,15],through:[1,5,7,13,14,18],thun:[2,3,4,9],thunder:7,time:[3,5,7,8,10,14],to_set:10,todai:7,todo:[7,16],togeth:[6,7,15],token:16,toler:15,tool:7,top:[2,3,7,17,18],total:5,trace:[0,7,11,14,15,18],traceprint:17,track:14,tracker:0,transform:4,translat:4,travers:[0,15],treasur:0,treat:[0,2,3,15],treatment:6,tree:[0,7,15],treegrind:15,treestep:[0,15],tri:5,trick:5,trobe:0,trove:0,truediv:11,truthi:[3,7],tuck:[3,7],tupl:[3,7,18],turn:[2,3],twice:10,two:[2,3,5,7,8,10,13,14,15,18],type:[1,4,7,10,16,17,18],typic:[2,3],unari:7,unarybuiltinwrapp:3,unbalanc:[10,16],unchang:10,uncon:[3,6,7,10,13,14],under:[2,3,7,10],understand:[0,10],undistinguish:10,undocu:7,unfortun:18,uniqu:[3,10],unit:7,univers:[0,7],unnecessari:15,unpack:[2,3,10,18],unpair:5,unquot:[7,13],unstack:3,until:6,unus:5,unusu:10,updat:[0,15],usag:7,use:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,18],used:[3,4,7,10,14,16,18],useful:0,user:13,uses:[2,5],using:[3,6,10,11,13,14],usual:[0,2],util:[0,12],valu:[0,2,3,5,7,8,12,13,15,18],value_n:10,valueerror:18,variabl:15,variant:10,variat:15,varieti:[4,7],variou:0,vener:18,verbos:4,veri:[0,1,4,7,10,18],versa:2,version:[0,1,2,6,9,11,13,14,15],via:7,vice:2,view:[10,15],viewer:[1,7,9,17],von:[0,2,3,4],wai:[0,2,3,4,5,7,12],want:[2,5,6,8,10],warranti:[3,7],wash:7,wast:7,web:18,websit:[0,5],welcom:7,well:[0,4,7,8,10,16],were:[7,14],what:[2,3,4,7,10,11,13,17],whatev:[2,3,13,18],when:[5,6,7,10,14,16,18],where:[2,3,7,10,15,18],which:[0,1,3,5,7,8,10,13,14,18],whole:[2,3,5,13],whose:6,why:[8,13],wiki:10,wikipedia:[0,10,14],wildli:7,wind:7,within:[7,10,12,15],without:[2,7,10],won:[10,18],word:[0,3,5,7,14],work:[0,3,5,6,7,8,10,13,14,18],worth:5,would:[2,5,6,7,8,10,14,18],wrap:[3,7],write:[4,8,10,13,14,15,18],written:[0,1,8,10,12,18],wrong:2,year:7,yet:[10,14],yield:[2,3,18],you:[0,2,3,5,6,7,9,10,12,13,14,17,18],your:[2,3,7],yourself:[7,10],zero:[3,10,13,16,18],zip:5,zip_:3,zipper:[0,15],zstr:14},titles:["Thun 0.2.0 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","Developing a Program in Joy","Using x to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Replacing Functions in the Dictionary","Treating Trees II: treestep","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026"],titleterms:{"case":[8,10],"function":[2,3,7,8,10,11,12,13],"long":12,"new":10,"void":2,"while":2,Adding:10,One:[6,10],The:[5,7,10,13],There:7,Using:6,With:13,about:15,add:[2,10],adding:10,address:14,altern:13,analysi:5,anamorph:2,app1:2,app2:2,app3:2,appendix:10,approxim:8,averag:2,base:[8,10],binari:[2,10,13],both:10,branch:[2,10],can:10,categor:4,chatter:2,check:11,child:10,choic:2,cleanup:11,clear:2,cleav:2,cmp:10,code:[7,10],combin:[2,10],compar:10,comparison:2,compil:6,comput:8,con:2,concat:2,consecut:8,continu:7,current:10,datastructur:[7,10,14],defin:[10,11,13],definit:11,delet:10,deriv:[11,13],determin:14,develop:5,dialect:0,dictionari:12,dip:[2,14],dipd:2,dipdd:2,direco:6,disenstacken:2,div:2,document:0,doe:10,down_to_zero:2,drop:2,dup:2,dupd:2,dupdip:2,els:10,empti:10,enstacken:2,equal:10,essai:15,euler:[5,6],eval:7,even:6,exampl:[2,7,10,13],execut:17,express:[7,16],extract:13,fibonacci:6,filter:5,find:[8,10],first:[2,5],five:6,flatten:2,flexibl:13,floordiv:2,formula:11,found:10,further:5,gcd:2,gener:[5,6,8],genrec:2,get:[10,13],getitem:2,given:13,greater:10,group:2,have:[10,13],help:2,highest:10,host:0,how:[5,6],ift:2,indic:0,inform:0,infra:[2,14],integ:5,interest:6,interlud:10,intern:16,interpret:[1,7],item:14,iter:[5,10],joi:[0,1,3,5,7,14,15,16,17,18],just:5,kei:10,languag:0,least_fract:2,left:10,less:10,let:5,librari:[3,7],like:10,list:[2,18],literari:7,littl:5,logic:2,loop:[2,7],lower:10,lshift:2,make:[6,8],mani:5,map:2,math:2,method:8,min:2,miscellan:2,mod:2,modulu:2,more:10,most:10,mul:2,multipl:[5,6],must:10,name:11,nativ:11,neg:2,newton:8,next:8,node:10,non:10,now:10,nullari:2,one:7,onli:7,order:[10,13],osdn:0,our:10,over:2,pack:5,pam:2,parameter:[10,13],pars:[2,16],parser:[7,16],pass:7,path:14,per:10,pop:2,popd:2,popop:2,pow:2,power:6,pred:2,predic:[5,8,10,13],pretty_print:17,primrec:2,print:7,problem:[5,6],process:10,product:2,program:[4,5,11,13,15],project:[0,5,6],pure:7,put:[10,13],python:[7,12],quadrat:11,quick:0,quot:[2,18],rang:[2,5],range_to_zero:2,read:7,recur:[8,10],recurs:[10,13],redefin:[10,13],refactor:[5,10],refer:3,regular:7,reimplement:13,rem:2,remaind:2,remov:2,render:5,repl:7,replac:[10,12],reset:6,rest:2,revers:2,right:[10,14],rightmost:10,roll:2,rolldown:2,rollup:2,rshift:2,run:[2,6],second:2,select:2,sequenc:[6,18],set:[8,10],shorter:12,should:7,shunt:2,simplest:5,simplifi:11,size:[2,12],sourc:10,sqr:2,sqrt:2,stack:[2,7,18],start:0,step:[2,13],straightforward:11,structur:10,style:7,sub:[2,10],succ:2,sum:[2,5],swaack:2,swap:2,swon:2,swoncat:2,symbol:7,tabl:0,take:2,term:[5,6,13],ternari:2,text:16,than:10,thi:10,third:2,three:6,thun:[0,7],time:[2,6],togeth:[10,13],token:7,toler:8,trace:[12,17],traceprint:7,travers:[10,13,14],treat:[10,13],tree:[10,13,14],treegrind:13,treestep:13,truediv:2,truthi:2,tuck:2,two:6,unari:2,uncon:2,unit:2,unnecessari:5,unquot:2,unstack:2,updat:9,util:[17,18],valu:[6,10],variabl:11,variat:6,version:[5,10,12],view:7,within:8,word:2,write:11,xor:2,zero:6,zip:2,zipper:14}})
\ No newline at end of file
+Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Recursion_Combinators","notebooks/Replacing","notebooks/Treestep","notebooks/Types","notebooks/Zipper","notebooks/index","parser","pretty","stack"],envversion:52,filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Recursion_Combinators.rst","notebooks/Replacing.rst","notebooks/Treestep.rst","notebooks/Types.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst"],objects:{"joy.joy":{joy:[1,1,1,""],repl:[1,1,1,""],run:[1,1,1,""]},"joy.library":{"void":[3,1,1,""],BinaryBuiltinWrapper:[3,1,1,""],DefinitionWrapper:[3,2,1,""],FunctionWrapper:[3,1,1,""],SimpleFunctionWrapper:[3,1,1,""],UnaryBuiltinWrapper:[3,1,1,""],add_aliases:[3,1,1,""],app1:[3,1,1,""],app2:[3,1,1,""],app3:[3,1,1,""],b:[3,1,1,""],branch:[3,1,1,""],choice:[3,1,1,""],clear:[3,1,1,""],cmp_:[3,1,1,""],concat_:[3,1,1,""],cond:[3,1,1,""],cons:[3,1,1,""],dip:[3,1,1,""],dipd:[3,1,1,""],dipdd:[3,1,1,""],divmod_:[3,1,1,""],drop:[3,1,1,""],dup:[3,1,1,""],dupd:[3,1,1,""],dupdip:[3,1,1,""],first:[3,1,1,""],floor:[3,1,1,""],genrec:[3,1,1,""],getitem:[3,1,1,""],help_:[3,1,1,""],i:[3,1,1,""],id_:[3,1,1,""],ifte:[3,1,1,""],infra:[3,1,1,""],initialize:[3,1,1,""],inscribe:[3,1,1,""],loop:[3,1,1,""],map_:[3,1,1,""],max_:[3,1,1,""],min_:[3,1,1,""],over:[3,1,1,""],parse:[3,1,1,""],pm:[3,1,1,""],pop:[3,1,1,""],popd:[3,1,1,""],popdd:[3,1,1,""],popop:[3,1,1,""],pred:[3,1,1,""],remove:[3,1,1,""],rest:[3,1,1,""],reverse:[3,1,1,""],rolldown:[3,1,1,""],rollup:[3,1,1,""],select:[3,1,1,""],sharing:[3,1,1,""],shunt:[3,1,1,""],sort_:[3,1,1,""],sqrt:[3,1,1,""],stack_:[3,1,1,""],step:[3,1,1,""],succ:[3,1,1,""],sum_:[3,1,1,""],swaack:[3,1,1,""],swap:[3,1,1,""],take:[3,1,1,""],times:[3,1,1,""],tuck:[3,1,1,""],uncons:[3,1,1,""],unique:[3,1,1,""],unstack:[3,1,1,""],warranty:[3,1,1,""],words:[3,1,1,""],x:[3,1,1,""],zip_:[3,1,1,""]},"joy.library.DefinitionWrapper":{add_def:[3,3,1,""],add_definitions:[3,3,1,""],parse_definition:[3,3,1,""]},"joy.parser":{ParseError:[18,4,1,""],Symbol:[18,2,1,""],text_to_expression:[18,1,1,""]},"joy.utils":{pretty_print:[19,0,0,"-"],stack:[20,0,0,"-"]},"joy.utils.pretty_print":{TracePrinter:[19,2,1,""]},"joy.utils.pretty_print.TracePrinter":{go:[19,5,1,""],viewer:[19,5,1,""]},"joy.utils.stack":{concat:[20,1,1,""],expression_to_string:[20,1,1,""],iter_stack:[20,1,1,""],list_to_stack:[20,1,1,""],pick:[20,1,1,""],stack_to_string:[20,1,1,""]},joy:{joy:[1,0,0,"-"],library:[3,0,0,"-"],parser:[18,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","classmethod","Python class method"],"4":["py","exception","Python exception"],"5":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:classmethod","4":"py:exception","5":"py:method"},terms:{"0b11100111011011":5,"23rd":15,"4ac":[],"5bkei":10,"\u03b5":8,"abstract":[7,10,17],"boolean":[2,3,7,10],"break":[7,15],"byte":5,"case":[2,3,12,14,15,20],"class":[3,7,15,18,19,20],"default":[3,6,10,20],"export":[3,18],"final":[2,10,12],"float":[3,7,15,16,18],"function":[0,1,4,5,6,9,11,16,17,18,19,20],"g\u00e9rard":16,"import":[2,5,6,8,10,11,12,13,14,15,16],"int":[6,7,12,15,16,18,20],"long":[10,17],"new":[2,3,6,7,9,12,13,15],"p\u00f6ial":17,"p\u00f6ial06typingtool":15,"public":9,"return":[1,3,5,7,10,12,13,14,15,18,19,20],"short":[],"static":[2,9],"switch":[2,15],"throw":10,"true":[2,3,5,12,15],"try":[6,8,11,12,14,15],"void":[0,3],"while":[3,7,10,15,18,20],Adding:[7,13,17],And:[5,6,8,10,12,15,16,20],But:[0,4,5,6,7,10,13,15],CPS:7,For:[2,3,10,12,13,15,17,20],Has:3,Its:3,One:[2,7,15,17],TOS:[2,3],That:[5,10],The:[0,1,2,3,4,6,8,9,11,15,16,17,18,20],Then:[2,3,10,11,12,15],There:[11,12,14,15,20],These:[15,17,20],Use:[3,8,12],Using:[0,8,10,17],With:[8,12,15,17],_1000:15,__add__:15,__class__:15,__eq__:15,__ge__:15,__hash__:15,__init__:15,__main__:15,__radd__:15,__repr__:15,__str__:19,_names_for:15,_to_str:15,_tree_add_:10,_tree_add_e:10,_tree_add_p:10,_tree_add_r:10,_tree_add_t:10,_tree_delete_:10,_tree_delete_clear_stuff:10,_tree_delete_del:10,_tree_delete_r0:10,_tree_delete_r1:10,_tree_delete_rightmost:10,_tree_delete_w:10,_tree_get_:10,_tree_get_p:10,_tree_get_r:10,_tree_get_t:10,_tree_iter_order_curr:10,_tree_iter_order_left:10,_tree_iter_order_r:10,_tree_iter_order_right:10,_tree_t:10,_treestep_0:14,_treestep_1:14,_uniqu:15,_within_b:8,_within_p:8,_within_r:8,abbrevi:14,abl:15,about:[0,7,10,16,20],abov:[0,5,8,10,12,15],abs:8,absolut:7,accept:[1,2,3,5,6,7,10,11,13,14,15,16],accomplish:[],accordingli:10,accumul:5,action:[7,13,15,16],actual:[2,5,7,10,15],adapt:17,add:[3,5,6,7,13,15,19],add_alias:3,add_def:3,add_definit:[3,10,14],added:[4,10],adding:[9,15],addit:[0,2,3,5,7,12,13,14],address:17,adjust:10,after:[5,6,7,12],afterward:7,again:[2,3,5,7,10,12,15],aggreg:[3,16],ahead:15,aka:[7,16],albrecht:0,algorithm:[7,15],alia:3,alias:[3,7],align:[7,19],all:[3,5,6,7,10,12,13,14,15,19],alloc:15,allow:[9,10],almost:10,along:[7,12],alphabet:3,alreadi:[8,13,15,16],also:[0,5,7,10,15,20],alter:15,altern:4,although:[4,10],altogeth:6,alwai:[5,9,12],among:15,amort:10,analysi:[4,17],anamorph:[7,17],ani:[4,5,7,9,10,15,16,18],annual:7,anonym:10,anoth:[10,20],anyjoytyp:15,anymor:15,anyth:[2,3,7,15],api:9,app1:3,app2:[3,7,11,12,13],app3:3,app:7,appear:[2,4,5,10],append:15,appendix:17,appli:[2,3,5,6,10,12,15],applic:6,approach:5,approxim:17,archiv:0,aren:16,arg:[2,3],argument:[2,3,7,8,11,12,17,19,20],arithmet:2,ariti:2,around:[5,20],arrang:14,arriv:[6,14],articl:[0,4,6,12],ask:[4,6,15],aspect:0,assert:15,assign:20,associ:10,assum:8,asterisk:14,attack:7,attempt:[0,1],attribut:3,attributeerror:15,author:15,automat:[4,15],auxiliari:14,avail:[0,15],averag:[7,13],avoid:10,awai:10,awar:2,awkward:[10,12],azur:17,back:10,backward:[9,10,11,14],bag:7,banana:12,barb:12,base:[0,2,3,9,12,14],basic:[1,2,3,7,10],becaus:[2,3,7,10,14,15,16,20],becom:[10,14,20],been:[8,9,10,15,16],befor:[6,7,10],begin:[10,14],behavior:[9,14],behaviour:[0,1,15],being:0,below:[2,3,5,6,10,15,16],bespok:7,best:0,better:[5,10,12],between:[0,5],beyond:6,biannual:7,binari:[0,6,7,17],binary_search_tre:10,binarybuiltinwrapp:3,bind:7,bingo:16,bit:[5,6,10,15],block:5,bodi:[2,7,10],body_text:3,booktitl:15,bool:12,borrow:7,both:[2,5,7,11,12,13,15,20],bottom:6,bracket:[7,15,18],branch:[3,5,6,12],breakpoint:7,bring:[5,7],bruijn:15,btree:[10,14],buck:10,bug:[0,7],build:[6,7,11,12,16,20],built:[11,15],bundl:[2,3,12],burgeon:7,calculu:4,call:[2,7,9,10,12,15,19,20],caller:10,can:[0,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,20],cannot:15,captur:7,card:7,care:[5,20],carefulli:16,carri:[6,10],cartesian:4,catamorph:17,categor:[0,17],categori:4,ccc:4,ccon:[10,15],cell:[12,15],certain:[7,20],certainli:10,chain:3,chang:[2,9,10,15,16],charact:16,chat:7,chatter:[0,15],check:[6,8,15],child:14,choic:[3,12],choos:9,chop:11,cinf:10,circuit:4,cite_not:10,classmethod:3,claus:[3,15],clean:15,clear:[3,5,7],clear_stuff:10,cleav:[7,11,13],close:[0,1,4],clunki:[5,15],cmp:[3,14,17],cmp_:3,code:[0,1,4,11,12,15,17],codireco:[6,8],collaps:12,collect:[4,6,7,15],combin:[0,3,5,6,7,8,11,14,16,17],come:[7,10],command:[7,10,15],common:[2,5],compar:[3,4,15],comparison:[0,10],compel:4,compil:[2,4,7,10,13,17],compile_:[],complet:4,complex:[3,15,16],complic:15,compos:[],composit:15,compound:10,comput:[2,4,5,7,11,15],con:[3,5,6,7,8,10,11,12,14,16,20],conal:4,concat:[3,6,7,14,17,20],concat_:3,concaten:0,concatin:[0,3,20],conclus:17,concurr:2,cond:[3,10],condit:[3,7],confer:15,conflict:[10,15],consecut:17,consid:[5,6,10,12,14,15,16],consist:[2,6,7,14],constant:10,constitu:12,construct:15,consum:15,contain:[0,2,3,6,7,12],context:2,conting:10,continu:[0,12,16],control:7,conveni:[4,15],convers:15,convert:[12,13,14,15,18,20],cool:10,copi:[2,3,5,10,12,14,17],copyright:7,correspond:4,could:[2,4,5,7,9,10,15,16],count:3,counter:[5,15],coupl:14,cours:[5,10],crack:10,crash:10,creat:[0,2,3,5,8,10,15],creativ:15,crude:[10,15,18],current:[2,3,7,12,14,16,19],custom:9,cycl:[5,6],cython:7,dai:7,data:[2,3,12],datastructur:[0,2,12,15,17,18,20],datatyp:20,ddididi:16,de_bruijn_index:[],deal:[0,10],dealt:15,decid:10,declar:15,decor:3,decoupl:12,decrement:3,deduc:[5,15],deeper:0,deepli:4,def:[3,7,12,13,15,20],defaultdict:15,defi:3,defin:[2,3,4,5,6,7,8,9,11,12,13,15,16,17],definit:[2,3,5,6,7,9,10,12,14,15,17],definitionwrapp:[3,10,12,14],delabel:[],deleg:7,delet:17,deliber:15,demonstr:4,depend:[3,10,12],deposit:14,dequot:12,der:10,deriv:[2,3,5,7,8,10,15,17],describ:[3,4,10,12,14,15,18],descript:[5,7],descriptor:15,design:[2,3,10,17],desir:[7,14],destruct:10,detail:[7,10,15],detect:[6,10,12,15],determin:17,develop:[0,6,7,15,17],diagram:5,dialect:1,dict:[1,3,15],dictionari:[0,1,3,7,17],differ:[0,4,5,8,10,11,12,20],differenti:4,dig:[10,16],digit:5,dinfrirst:7,dip:[3,5,6,7,8,10,11,12,13,14,15,17],dipd:[3,6,7,10,11,12,16],dipdd:[3,10],direco:17,direct:7,directli:[5,14,15,20],disappear:2,discard:[3,6,8,10,12],disciplin:10,disenstacken:7,disk:7,displac:2,displai:15,distiguish:15,distinguish:[],ditch:10,div:[3,7],dive:14,divis:10,divmod:3,divmod_:[3,15],doc:[2,3,7,15],doc_from_stack_effect:[],document:[17,18,20],doe:[0,1,4,6,7,13,17,19],doesn:[5,9,10,14,15,20],doing:[4,5,7,15,16],domain:[4,15],don:[5,7,10,15],done:[2,5,7,9,15],door:7,dot:19,doubl:[5,7,15],down:[2,3,8,12,16],down_to_zero:7,dozen:7,draft:[4,9],dream:7,drive:[6,8],driven:5,driver:6,drop:[3,10],dudipd:7,due:15,dup:[3,5,6,7,8,10,11,12,16,20],dupd:[3,15],dupdip:[3,5,10,11,12],duplic:[3,10,12],durat:2,dure:[2,12],each:[2,3,4,5,7,12,13,14,15,19],easi:[0,10,14,15,16],easier:[3,10],easili:4,edit:17,effect:[2,3,7,16,17],effici:[6,13,16],either:[1,2,3,10,12,15],eleg:[7,10,15],element:[2,3],elif:15,elimin:15,elliott:4,els:[2,3,12,17],embed:[4,10,16],emit:15,empti:[3,7,14,15,20],encapsul:7,enclos:7,encod:6,encount:15,end:[5,10,12,14,15,20],endless:6,enforc:[2,7],engend:7,enough:[7,12,19],enstacken:[6,7,15],enter:7,entir:20,entri:[3,16,19],enumer:15,epsilon:8,equal:[5,14,20],equat:[7,8],ergo:10,err:10,error:[7,18],essai:0,establish:15,etc:[3,14,15,16,18],euler:17,euro:15,eval:[0,15],evalu:[1,2,3,7,8,10,11,12,13,14],eventu:[],everi:6,everyth:[3,10,11,15],evolv:9,examin:12,exampl:[0,3,5,17,18,20],exce:6,except:[7,10,15,18],execut:[0,1,2,3,7,12,13,14,16,20],exercis:10,exist:[4,10],expand:10,expect:[2,3,14,20],experi:[7,14],explain:15,explan:7,explor:7,express:[0,1,2,3,4,10,12,13,15,16,19,20],expression_to_str:20,extend:15,extra:[5,6],extract:[10,11,17],extrem:7,extrememli:7,f_g:15,f_in:15,f_out:15,f_python:15,facet:0,facil:7,fact:18,factor:[2,5,7,10,15],factori:17,fail:[2,3,10,18],fairli:15,fals:[2,3,5,12,15],far:[8,10,12,15],fascin:0,fear:[10,15],few:[5,7,8,11],fewer:[3,7],fg_in:15,fg_out:15,fib:6,fib_gen:6,fibonacci:17,figur:[2,3,10,12],filter:10,fin:5,find:[2,3,5,6,14,15,17],finder:8,fine:[0,5,10,15],finish:[],first:[3,6,7,8,10,11,12,13,14,16,17],first_two:10,fit:[5,7],five:[5,7,17],fix:[2,3,12],flatten:[7,14],flexibl:17,floatjoytyp:15,floor:3,floordiv:5,flow:7,follow:[0,2,3,7,9,12,14,15,16],foo:[7,9,10,15],foo_ii:9,form:[2,3,4,5,6,12,14,15,20],forman:7,format:[15,17,19],formula:[0,5,17],forth:[7,15],forum:0,found:7,four:[2,3,5,6,7,10,17],fourteen:5,fourth:[2,3,10,12],fractal:7,fraction0:7,fraction:[2,7],frame:12,framework:7,free:[4,7,10],freeli:2,from:[0,1,2,3,5,6,7,8,10,11,12,13,14,15,16,17,20],front:[2,3,12],full:5,fun:17,func:15,functionwrapp:3,funtion:10,further:[8,17],futur:[],g_in:15,g_out:15,garbag:7,gari:10,gcd:7,gener:[0,2,3,4,12,15,17,20],genrec:[3,7,10,12,14],geometr:5,get:[2,4,5,6,7,11,12,15,17],getitem:3,getrecursionlimit:20,getsourc:7,ghc:4,give:[4,5,10,12,14,15,20],given:[2,3,5,6,8,10,12,16,17],global:15,glue:7,going:[10,11,14,15,16],good:[5,10,15],grab:[3,15],grammar:18,grand:7,great:[0,7,17],greater:20,group:0,gsra:8,guard:10,had:[5,16],haiku:7,half:[5,16],hand:[7,13,15,17],handi:[8,15],handl:[10,15,20],happen:[7,15],hard:[15,16],hardwar:4,has:[0,2,6,7,8,9,10,12,15,16,20],hash:15,haskel:4,have:[2,3,5,6,7,8,9,12,13,15,16,17,20],head:20,help:[7,10,12,15],help_:3,helper:3,herd:7,here:[5,6,10,14,15,16],hide:10,hierarchi:15,higher:[7,10],highli:7,histori:19,hmm:10,hoist:3,hold:[5,15],hood:10,hope:[0,5,7,17],hopefulli:12,host:17,how:[0,4,8,10,12,15,16,17],howev:[12,13,15],html:[2,3,6,11,12,17],http:10,huet:16,huge:10,hugh:[8,14],human:7,hylomorph:17,hypothet:2,id_:3,idea:[4,5,7,15],ident:[3,12],identifi:[],if_not_empti:10,ift:[3,10,12,14],ignor:[3,10,15],illustr:12,imagin:16,imap:15,imit:14,immedi:12,immut:[7,10],imper:12,implement:[0,1,2,3,4,7,9,10,12,13,17],implicit:7,includ:[4,10,14],inclus:5,incom:20,incompat:9,incorpor:11,increas:5,increment:[3,4,5,9],index:[0,7,15,20],indexerror:20,indic:[14,15],ineffici:15,infer:[0,17],inform:[3,15],infra:[3,6,7,10,11,13,14,17],infrastructur:3,initi:[2,3,7,8,10],inlin:10,inner:15,inproceed:15,input:[1,8,15],inscrib:3,insight:12,inspect:7,instal:0,instanti:[4,19],instead:[5,6,10,12,15,16,20],integ:[2,3,7,12,14,15],integr:3,intend:[0,7],interact:[7,17],interest:[0,5,10,15,17],interlud:17,intermedi:12,intern:[0,15,19,20],interpret:[0,4,9,13,17,18,19],interrupt:7,interv:[4,5],intjoytyp:15,introduc:9,introduct:0,intuit:15,invari:3,invers:3,involv:15,ipf:7,isinst:15,isn:[10,16],issubclass:15,item:[2,3,7,10,12,14,15,17,20],iter:[1,3,7,12,14,15,17,20],iter_stack:[13,20],iteritem:15,itertool:15,its:[0,2,3,4,5,7,10,12,14,15,20],itself:[0,2,7,10,15],j05cmp:[2,3,12],jaanu:15,job:17,john:[8,14],joi:[2,4,9,10,11,13,15],join:15,joypi:[7,16],junk:15,jupyt:17,just:[0,2,3,6,7,9,10,12,14,15,16],keep:[10,11,15,16],kei:[14,17],kevin:0,key_n:10,keyerror:[10,15],kind:[2,4,7,10,12,14],kleen:14,know:[5,10],known:4,l_kei:10,l_left:10,l_right:10,l_valu:10,label:15,lambda:[4,15],languag:[4,7,9,10,13,15],larger:20,largest:3,last:[5,10,12,15],lastli:6,later:[7,14,15],law:2,lazi:15,lazili:8,lcm:5,lead:7,leaf:10,lean:7,learn:0,least:[2,5,12,15,20],least_fract:7,leav:5,left:[7,11,12,14,15,16,19,20],leftov:12,len:15,length:[3,5,20],lens:12,less:[5,6,7,12,15,20],let:[6,8,10,11,12,14,15,16],level:[4,10],librari:[0,13],like:[2,3,5,7,14,15,17,18],limit:15,line:[3,7,10,11,19],linear:20,link:0,linux:0,list:[0,3,5,7,8,10,12,14,16,19],list_to_stack:20,liter:[1,10,14,15,16,18],littl:[6,10,15,17],live:17,lkei:14,load:[5,7],local:15,locat:2,locu:19,log_2:10,logic:[0,5],longer:[10,15],look:[6,7,8,10,11,15],lookup:7,loop:[0,1,3,5],lose:15,lot:[7,10,16],love:5,low:4,lower:5,lowest:10,machin:0,machineri:[10,15],macro:7,made:[0,7,15,16],magic:15,mai:[2,12],mail:0,main:[0,3,7,11,15,16],mainloop:9,maintain:16,major:9,make:[2,3,4,5,7,10,12,13,14,15,16,17],make_gener:8,manfr:[0,2,3,4,12],mani:[0,7,15],manipul:15,manner:11,map:[1,3,5,7,9,12,14,15],map_:3,marker:7,mask:[5,6],match:[0,1],materi:0,math:[0,7,8,10,11,15],mathemat:7,matter:[5,8,10,14],max_:3,maximum:3,mayb:10,mean:[4,5,7,8,10,12,14,20],meant:[7,10,12,14],member:[2,3,12],mental:7,mention:2,mercuri:0,mess:15,meta:[7,10,13],method:[0,3,7,15,17,19],midpoint:5,might:[4,6,10,15],mike:10,million:6,min_:3,mind:15,minimum:3,minor:10,minu:3,mirror:0,miscellan:0,mix:7,mod:3,model:[4,7],modern:0,modif:6,modifi:[7,10,16],modul:[0,1,3,7,18],modulu:7,moment:15,month:7,more:[0,3,4,5,6,7,8,12,13,14,15,18,20],most:15,mostli:0,move:10,movement:2,much:[5,6,10,12,15],muck:10,mul:[7,11,16,19],multi:3,multipl:17,must:[2,3,5,9,12,14,15],myself:15,n1001:15,n1002:15,n1003:15,name:[1,3,7,9,10,12,15,16,17,18,20],natur:[5,6,10],navig:16,nearli:15,neat:10,neato:15,necessarili:15,need:[2,3,5,6,8,9,10,12,15],neg:[3,11],nest:[3,7,10,16],network:7,never:[9,12],new_def:15,new_kei:10,new_valu:10,newton:[0,17],next:[5,14,15],nice:[0,12,20],niether:2,node:[14,17],node_kei:10,node_valu:10,non:14,none:[1,3,15],nope:14,notat:[7,10],note:[2,5,8,10,12,15,20],notebook:[5,6,7,15,16,17],notebook_preambl:[2,5,6,8,10,11,12,13,14,15,16],noth:[2,10],notic:5,now:[5,6,7,12,13,14,15,17],nth:[3,20],nullari:[7,10],number:[1,2,3,5,6,8,20],numberjoytyp:15,numer:15,object:[15,18],observ:5,obviou:[6,15],occur:10,odd:[5,6],off:[2,3,5,6,11,16],old:[2,13],old_k:10,old_kei:10,old_valu:10,omit:[12,15],onc:[3,9,10],one:[2,3,5,6,10,12,14,15,19,20],ones:[6,15],onli:[2,3,5,10,12,15,16,20],onto:[1,2,3,7,12,20],open:[7,15],oper:[3,7,10,12,20],oppos:15,optim:10,option:[1,7,10,20],order:[0,2,3,7,12,15,17,20],org:[0,10],origin:[0,1,2,3,10,16],other:[0,2,3,4,7,10,12,14,15,20],otherwis:[3,5,6,10,14,15],our:[5,6,7,8,12,14,15],out:[2,3,4,5,6,7,8,10,11,12,15,16],outcom:14,output:[8,12,15],outsid:4,over:[3,4,5,6,7,8,10,11,14,15,17],overhaul:15,own:[10,15],pack:20,packag:[0,7],page:[0,10,15,20],pair:[2,3,5,6,10,15],palidrom:5,palindrom:5,pam:7,paper:[4,7,12,16],parallel:2,paramet:[1,2,3,12,13,18,19,20],parameter:17,paramorph:12,parenthes:[10,20],pariti:6,pars:[0,3,7],parse_definit:3,parseerror:18,parser:[0,15],part:[2,3,8,12,14,15],partial:15,particular:16,pass:[0,10,15,19],path:17,pattern:[5,14,17],pe1:[5,6],pe2:6,pearl:16,pend:[3,7,12,16,19],peopl:17,per:[7,14],perform:15,perhap:6,period:7,permit:[15,20],permut:15,persist:10,phase:2,pick:[5,6,20],pickl:7,pictur:10,piec:12,pip:0,place:[3,5,7],plai:0,plu:3,plug:[6,12,14],point:[4,7,10,12],pointless:2,pop:[3,5,6,7,10,12,13,14,20],popd:[3,7,8,10,13,15],popdd:[3,6,11,15],popop:[3,5,6,7,8,10,14,15],posit:[3,5,7,12],possibilit:10,possibl:[10,14,15,17],post:7,poswrd:15,poswro:[],potenti:3,power:7,pragmat:5,preambl:8,precis:[0,1],pred:[3,15],predic:[2,3,6,12],prefix:[15,19],preserv:[4,14],pretti:[8,10,11,14,15,19,20],pretty_print:0,previou:7,prime:8,primit:[2,3,15,17],primrec:[3,6,7,8,12],print:[0,1,2,3,15,19,20],probabl:[6,7,10,15],problem:[7,15,17],proc_curr:10,proc_left:10,proc_right:10,proce:5,process:[7,14,15,19],produc:[5,10,12,14,15],product:[6,7],program:[0,2,3,6,7,8,10,12,16],programm:15,project:17,prompt:7,proper:[2,3,12],properti:0,provid:[0,3,4,7],psrd:[],pun:[0,7],punctuat:15,pure:0,puriti:7,purpos:7,push:[2,3,7,12,16,20],pushback:7,put:[1,2,6,7,15,17,20],pypi:0,python:[0,2,3,10,12,16,17,18,20],quadrat:[0,17],queri:[10,14],query_kei:14,queu:12,quit:[0,1,14],quot:[0,3,6,7,10,11,12,14,15,16,19],quotat:[2,3,12],quotient:3,r_kei:10,r_left:10,r_right:10,r_valu:10,rais:[10,15,18,20],rang:[7,15],range_revers:12,range_to_zero:7,ranger:12,ranger_revers:12,raphson:8,rather:[5,7,12,14],ratio:7,reach:[5,6,12],read:[0,1,5,6,10,15,16],readabl:13,reader:10,readi:15,real:10,realiz:[4,10],rearrang:[2,10,15],reason:[5,7,15],rebuild:[14,16],rec1:[2,3,12],rec2:[2,3,12],recogn:18,record:[7,19],recur:[12,15],recurs:[0,2,3,6,7,8,15,17,20],recus:7,redefin:17,redistribut:[3,7],reduc:[2,15],redund:20,refactor:[7,9],refer:[0,2],regist:2,regular:18,reimplement:17,rel:[],relabel:[],relat:15,releas:9,remain:[2,3,7,9],remaind:[3,8],remind:15,remov:[3,10,15,20],render:17,repeat:5,repeatedli:5,repl:[0,1],replac:[0,2,3,6,11,12,14,15,16,17,20],repositori:0,repr:15,repres:[2,7,10,18,19],represent:20,reprod:6,repurpos:15,requir:20,resembl:7,respect:5,rest:[3,5,6,7,10,12,16,17,20],rest_two:10,restor:2,restrict:15,result:[1,2,3,5,10,11,12,14,15,16],resum:7,retain:15,retir:2,retri:7,reus:[10,15],revers:[3,5,6,12,15,16,20],revisit:15,rewrit:[3,7,15],rewritten:7,rid:10,right:[6,7,11,14,15,17,19,20],rightest:10,rightmost:5,rkei:14,roll:[3,8,10,14],roll_dn:15,roll_down:15,roll_up:15,rolldown:3,rollup:3,root:[3,8,11],round:15,rrest:15,rule:17,run:[0,1,3,5,7,8,10,11,12,14,16],runtimeerror:20,sai:[6,10,11,14,15],same:[2,4,5,10,15,20],sandwich:[2,3,12],save:[2,5,7],scan:3,scanner:[7,18],scenario:16,scope:[6,10],search:[0,10],second:[3,7,10,12,14,20],section:12,see:[0,6,7,8,9,11,12,13,15,16,19],seem:[0,5,7,14,15],seen:[15,16],select:3,self:15,semant:[2,3,7,9,10,15],semi:7,send:7,sens:[0,2,5,15,16],separ:[7,15],seq:15,sequenc:[0,1,2,3,5,7,10,12,13,15,16,17,18],sequence_to_stack:15,seri:[5,6,10,16],set:[2,3,12,17],seven:[5,6],sever:[0,4,7,12],share:[3,7],shelf:2,shift:[5,6],shorter:17,shorthand:10,should:[2,3,5,10,12,15],shouldn:7,show:[4,16],shunt:[3,16],side:[10,15],signifi:[7,10],similar:[10,14,15],simon:7,simpl:[7,12,15,20],simplefunctionwrapp:[3,13,15],simpler:14,simplest:[15,17],simpli:4,simplifi:[5,10,16],sinc:[2,5,10],singl:[3,6,7,13,15,18],situ:10,situat:10,six:[5,6,7],sixti:[5,6],size:[7,17],skeptic:7,skip:15,slight:8,slightli:[10,12,15],smallest:3,smart:10,softwar:7,solei:2,solut:[5,6],solvabl:7,some:[2,3,6,7,10,12,14,15,17,20],somehow:[10,15],someth:[2,9,10,17],sometim:10,somewher:[10,17],sort:[3,10,15],sort_:3,sourc:[0,1,3,15,17,18,19,20],space:[5,19],span:5,special:[6,10,15,17],specif:[0,4],specifi:10,speed:13,spell:14,sphinx:[17,20],spirit:[0,1,14],sqr:[7,8,11,16],sqrt:[3,8,15],squar:[3,8,15,18],stack:[0,1,3,5,6,8,10,11,12,13,14,16,17,18,19],stack_:3,stack_concat:15,stack_effect_com:15,stack_to_str:20,stacki:15,stackjoytyp:15,stage:14,stai:[0,1],stand:4,standard:[7,10],star:14,stare:10,start:[5,6,7,8,10,12,14],state:7,statement:3,step:[3,5,7,10,13,15,16,17],still:[10,15],stop:10,storag:[5,10],store:[5,12],stori:12,str:[1,15,18,19,20],straightforward:[1,6,8,17],stream:5,stretch:10,string:[1,2,3,7,15,16,18,19,20],structur:[7,14,15,16,17,20],stuff:[10,15],style:[0,4,15],sub:9,subclass:7,subject:[15,16],subset:15,substitut:[10,15],subtract:5,subtyp:17,succ:[3,15],success:8,suffic:15,suffici:10,suffix:15,suggest:[4,10],suitabl:[3,4,5],sum:[3,6,7,11,12,13,14],sum_:3,summand:5,sumtre:14,suppli:[10,18],support:[7,19,20],suspect:2,swaack:[3,11,13,16],swap:[3,5,6,7,8,10,12,13,14,16],swon:[3,6,7,12,14,15,16],swoncat:[6,7,8,12,14],swuncon:12,symbol:[2,3,15,16,17,18],symmetr:[5,10],sympi:[],syntact:7,syntax:[7,20],sys:20,system:[7,10],tabl:15,tag:15,tail:[10,15,17,20],take:[3,5,7,8,10,12,15,20],talk:[7,10,20],target:16,tast:4,tbd:[7,15],tear:12,technic:2,techniqu:[4,16],technolog:2,temporari:16,ten:5,term:[1,2,7,8,12,15,17,18,20],termin:[2,3,12],ternari:7,test:[2,3,12],text:[0,1,3,15],text_to_express:[7,18],textual:7,than:[0,3,5,6,7,8,12,14,20],thei:[2,5,6,7,10,12,15,16,18,20],them:[2,3,5,6,10,12,15,16,17],themselv:15,theori:[2,3,12],therefor:6,thi:[0,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20],thing:[2,6,10,12,15,16,18,20],think:[2,5,7,10,12,14],third:[3,6,7,10],thirti:5,those:[2,3,10,12,15,17],though:5,thought:7,thousand:5,thread:2,three:[2,3,5,7,10,11,14,15,17],through:[1,5,7,14,15,16,20],thun:[2,3,4,9,12],thunder:7,time:[3,5,7,8,10,12,15,16],titl:15,to_set:10,todai:7,todo:[7,18],togeth:[6,7,15,17],token:18,toler:17,too:[12,15],tool:[7,15],top:[2,3,7,12,15,19,20],total:5,tower:15,trace:[0,7,11,12,16,17,20],traceprint:19,track:[11,15,16],tracker:0,transform:4,translat:[4,11,15],travers:[0,17],treasur:0,treat:[0,2,3,12,17],treatment:6,tree:[0,7,17],treegrind:17,treestep:[0,17],tri:5,triangular_numb:12,trick:[5,15],tricki:15,trobe:0,trove:0,truediv:[],truthi:[3,7],tuck:[3,7,15],tupl:[3,7,15,20],turn:[2,3],twice:[10,12],two:[2,3,5,7,8,10,11,12,14,15,16,17,20],type:[0,1,4,7,10,12,17,18,19,20],typeerror:15,typeless:15,typic:[2,3,11,12],unari:7,unarybuiltinwrapp:3,unbalanc:[10,18],unchang:10,uncompil:15,uncon:[3,6,7,10,12,14,16],under:[2,3,7,10],underli:15,underscor:15,understand:[0,10],undistinguish:10,undocu:7,unfortun:20,unif:15,uniqu:[3,10,15],unit:[7,12],univers:[0,7],unnecessari:17,unnecesssari:15,unpack:[2,3,10,20],unpair:5,unquot:[7,14],unstack:[3,15],untangl:12,until:6,unus:5,unusu:10,updat:[0,17],usag:7,use:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,20],used:[3,4,7,10,12,16,18,20],useful:0,user:14,uses:[2,5,12],using:[3,6,10,11,12,14,16],usual:[0,2,12],util:[0,13],valid:15,valu:[0,2,3,5,7,8,11,12,13,14,15,17,20],value_n:10,valueerror:[15,20],variabl:17,variant:10,variat:[12,17],varieti:[4,7],variou:0,vener:20,verbos:4,veri:[0,1,4,7,10,20],versa:[2,15],version:[0,1,2,6,9,14,16,17],via:7,vice:[2,15],view:[10,17],viewer:[1,7,9,19],von:[0,2,3,4,12],wai:[0,2,3,4,5,7,12,13,15],want:[2,5,6,8,10,12,15],warranti:[3,7],wash:7,wast:7,web:20,websit:[0,5],welcom:7,well:[0,4,7,8,10,15,18],were:[7,15,16],what:[2,3,4,7,10,12,14,15,19],whatev:[2,3,12,14,20],when:[5,6,7,10,12,15,16,18,20],where:[2,3,7,10,12,17,20],whether:12,which:[0,1,3,5,7,8,10,12,14,15,16,20],whole:[2,3,5,12,14,15],whose:6,why:[8,14],wiki:10,wikipedia:[0,10,16],wildli:7,wind:7,wire:12,within:[7,10,13,17],without:[2,7,10,11],won:[10,15,20],word:[0,3,5,7,12,16],work:[0,3,5,6,7,8,10,11,12,14,15,16,20],worth:5,would:[2,5,6,7,8,10,12,15,16,20],wrap:[3,7],wrapper:15,write:[4,8,10,12,14,15,16,17,20],written:[0,1,8,10,13,15,20],wrong:2,wrote:15,xrang:15,year:[7,15],yet:[10,15,16],yield:[2,3,12,20],you:[0,2,3,5,6,7,9,10,11,12,13,14,15,16,19,20],your:[2,3,7,12,15],yourself:[7,10],zero:[3,10,12,14,18,20],zip:[5,15],zip_:3,zipper:[0,17],zstr:16},titles:["Thun 0.2.0 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","Developing a Program in Joy","Using x to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Recursive Combinators","Replacing Functions in the Dictionary","Treating Trees II: treestep","Type Inference","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026"],titleterms:{"abstract":15,"case":[8,10],"function":[2,3,7,8,10,12,13,14,15],"long":13,"new":10,"p\u00f6ial":15,"void":2,"while":2,Adding:10,One:[6,10],The:[5,7,10,12,14],There:7,Using:6,With:14,about:17,add:[2,10],adding:10,address:16,altern:14,ana:12,analysi:5,anamorph:[2,12],app1:2,app2:2,app3:2,appendix:[10,12],approxim:8,argument:15,averag:2,base:[8,10],binari:[2,10,14],both:10,branch:[2,10],can:10,cata:12,catamorph:12,categor:4,chatter:2,check:[],child:10,choic:2,cleanup:[],clear:2,cleav:2,cmp:10,code:[7,10],combin:[2,10,12,15],comment:15,compar:10,comparison:2,compil:[6,15],compile_:15,compos:15,comput:8,con:[2,15],concat:[2,15],conclus:12,consecut:8,continu:7,current:10,datastructur:[7,10,16],deal:15,defin:[10,14],definit:11,delabel:15,delet:10,deriv:[11,12,14],design:12,determin:16,develop:5,dialect:0,dictionari:13,dip:[2,16],dipd:2,dipdd:2,direco:6,disenstacken:2,distinguish:15,div:2,doc_from_stack_effect:15,document:0,doe:10,down_to_zero:2,drop:2,dup:[2,15],dupd:2,dupdip:2,effect:15,els:[10,15],empti:10,enstacken:2,equal:10,essai:17,euler:[5,6],eval:7,even:6,exampl:[2,7,10,12,14,15],execut:19,express:[7,18],extract:14,factori:12,fibonacci:6,filter:5,find:[8,10,12],first:[2,5,15],five:6,flatten:2,flexibl:14,floordiv:2,formula:11,found:10,four:12,fun:12,further:5,gcd:2,gener:[5,6,8],genrec:2,get:[10,14],getitem:2,given:14,greater:10,group:2,have:[10,14],help:2,highest:10,host:0,how:[5,6],hylo:12,hylomorph:12,identifi:15,ift:2,implement:15,indic:0,infer:15,inferenc:15,inform:0,infra:[2,16],integ:5,interest:6,interlud:10,intern:18,interpret:[1,7,15],item:16,iter:[5,10],joi:[0,1,3,5,7,12,16,17,18,19,20],just:5,kei:10,languag:0,least_fract:2,left:10,less:10,let:5,librari:[3,7,15],like:10,list:[2,15,20],literari:7,littl:5,logic:2,loop:[2,7],lower:10,lshift:2,make:[6,8],mani:5,map:2,math:2,method:8,min:2,miscellan:2,mod:2,modifi:15,modulu:2,more:10,most:10,mul:[2,15],multipl:[5,6],must:10,name:11,nativ:[],neg:2,newton:8,next:8,node:10,non:10,now:10,nullari:2,number:[12,15],one:7,onli:7,order:[10,14],osdn:0,our:10,over:2,pack:5,pam:2,para:12,parameter:[10,14],pars:[2,18],parser:[7,18],pass:7,path:16,pattern:12,per:10,pop:[2,15],popd:2,popop:2,pow:2,power:6,pred:2,predic:[5,8,10,14],pretty_print:19,primit:12,primrec:2,print:7,problem:[5,6],process:10,product:2,program:[4,5,11,14,17],project:[0,5,6],pure:7,put:[10,11,14],python:[7,13,15],quadrat:11,quick:0,quot:[2,20],rang:[2,5,12],range_to_zero:2,read:7,recur:[8,10],recurs:[10,12,14],redefin:[10,14],refactor:[5,10],refer:3,regular:7,reimplement:14,relabel:15,rem:2,remaind:2,remov:2,render:5,repl:7,replac:[10,13],repres:15,reset:6,rest:[2,15],revers:2,right:[10,16],rightmost:10,roll:[2,15],rolldown:2,rollup:2,rshift:2,rule:15,run:[2,6],second:[2,15],select:2,sequenc:[6,20],set:[8,10,15],shorter:13,should:7,shunt:2,simplest:5,simplifi:[],size:[2,13],someth:15,sourc:10,special:12,sqr:[2,15],sqrt:[2,11],stack:[2,7,15,20],start:0,step:[2,12,14],straightforward:11,structur:10,style:7,sub:[2,10],subtyp:15,succ:2,sum:[2,5],swaack:2,swap:[2,15],swon:2,swoncat:2,symbol:[7,12],tabl:0,tail:12,take:2,term:[5,6,14],ternari:2,text:18,than:10,them:11,thi:10,thing:[],third:[2,15],three:6,thun:[0,7],time:[2,6],togeth:[10,11,14],token:7,toler:8,trace:[13,19],traceprint:7,travers:[10,14,16],treat:[10,14],tree:[10,14,16],treegrind:14,treestep:14,triangular:12,truediv:2,truthi:2,tuck:2,two:6,type:15,unari:2,uncon:[2,15],unifi:15,unit:2,unnecessari:5,unquot:2,unstack:2,updat:[9,15],use:15,util:[19,20],valu:[6,10],variabl:11,variat:6,version:[5,10,13,15],view:7,within:8,word:2,write:11,xor:2,zero:6,zip:2,zipper:16}})
\ No newline at end of file
diff --git a/docs/sphinx_docs/_build/html/stack.html b/docs/sphinx_docs/_build/html/stack.html
index ce88245..5329c20 100644
--- a/docs/sphinx_docs/_build/html/stack.html
+++ b/docs/sphinx_docs/_build/html/stack.html
@@ -80,6 +80,31 @@ 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 internal stacks are
printed left-to-right. These functions are written to support Tracing Joy Execution.
+
+-
+
joy.utils.stack.concat(quote, expression)[source]¶
+Concatinate quote onto expression.
+In joy [1 2] [3 4] would become [1 2 3 4].
+
+
+
+
+Parameters:
+- quote (stack) – A stack.
+- expression (stack) – A stack.
+
+
+
+Raises: RuntimeError – if quote is larger than sys.getrecursionlimit().
+
+
+Return type: stack
+
+
+
+
+
+
-
joy.utils.stack.expression_to_string(expression)[source]¶
@@ -168,31 +193,6 @@ won’t work because
--
-
joy.utils.stack.pushback(quote, expression)[source]¶
-Concatinate quote onto expression.
-In joy [1 2] [3 4] would become [1 2 3 4].
-
-
-
-
-Parameters:
-- quote (stack) – A stack.
-- expression (stack) – A stack.
-
-
-
-Raises: RuntimeError – if quote is larger than sys.getrecursionlimit().
-
-
-Return type: stack
-
-
-
-
-
-
-
joy.utils.stack.stack_to_string(stack)[source]¶
diff --git a/docs/sphinx_docs/notebooks/Quadratic.rst b/docs/sphinx_docs/notebooks/Quadratic.rst
index 9975abb..60e312f 100644
--- a/docs/sphinx_docs/notebooks/Quadratic.rst
+++ b/docs/sphinx_docs/notebooks/Quadratic.rst
@@ -1,104 +1,92 @@
-`Quadratic formula `__
-=======================================================================
-
.. code:: ipython2
from notebook_preamble import J, V, define
+`Quadratic formula `__
+=======================================================================
+
Cf.
`jp-quadratic.html `__
::
- -b +/- sqrt(b^2 - 4 * a * c)
- -----------------------------
- 2 * a
+ -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 neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
-
-We use ``cleave`` to compute the sum and difference and then ``app2`` to
-finish computing both roots using a quoted program ``[2a truediv]``
-built with ``cons``.
-
-Check it.
-~~~~~~~~~
-
-Evaluating by hand:
+``-b``
+~~~~~~
::
- b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
- -b b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
- -b b^2 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
- -b b^2 4ac - sqrt [+] [-] cleave a 2 * [truediv] cons app2
- -b b^2-4ac sqrt [+] [-] cleave a 2 * [truediv] cons app2
- -b sqrt(b^2-4ac) [+] [-] cleave a 2 * [truediv] cons app2
+ b neg
- -b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) a 2 * [truediv] cons app2
- -b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) 2a [truediv] cons app2
- -b -b+sqrt(b^2-4ac) -b-sqrt(b^2-4ac) [2a truediv] app2
- -b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
+``sqrt(b^2 - 4 * a * c)``
+~~~~~~~~~~~~~~~~~~~~~~~~~
-(Eventually we’ll be able to use e.g. Sympy versions of the Joy commands
-to do this sort of thing symbolically. This is part of what is meant by
-a “categorical” language.)
+::
-Cleanup
+ b sqr 4 a c * * - sqrt
+
+``/2a``
~~~~~~~
::
- -b -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a roll< pop
- -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a -b pop
- -b+sqrt(b^2-4ac)/2a -b-sqrt(b^2-4ac)/2a
+ a 2 * /
-Derive a definition.
---------------------
+``±``
+~~~~~
-::
-
- b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
- b [neg] dupdip sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
- b a c [[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2 roll< pop
- b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop
- b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop
-
-.. code:: ipython2
-
- define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt [+] [-] cleave] dip 2 * [truediv] cons app2 roll< pop')
-
-.. code:: ipython2
-
- J('3 1 1 quadratic')
-
-
-.. parsed-literal::
-
- -0.3819660112501051 -2.618033988749895
-
-
-Simplify
---------
-
-We can define a ``pm`` plus-or-minus function:
+There is a function ``pm`` that accepts two values on the stack and
+replaces them with their sum and difference.
::
pm == [+] [-] cleave popdd
-Then ``quadratic`` becomes:
+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 it's the definition of the ``quadratic`` function:
.. code:: ipython2
- define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2')
+ define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
+
+Let's try it out:
.. code:: ipython2
@@ -110,74 +98,61 @@ Then ``quadratic`` becomes:
-0.3819660112501051 -2.618033988749895
-Define a "native" ``pm`` function.
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The definition of ``pm`` above is pretty elegant, but the implementation
-takes a lot of steps relative to what it's accomplishing. Since we are
-likely to use ``pm`` more than once in the future, let's write a
-primitive in Python and add it to the dictionary. (This has been done
-already.)
+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
- def pm(stack):
- a, (b, stack) = stack
- p, m, = b + a, b - a
- return m, (p, stack)
-
-The resulting trace is short enough to fit on a page.
-
-.. code:: ipython2
-
- V('3 1 1 quadratic')
+ V('-5 1 4 quadratic')
.. parsed-literal::
- . 3 1 1 quadratic
- 3 . 1 1 quadratic
- 3 1 . 1 quadratic
- 3 1 1 . quadratic
- 3 1 1 . over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2
- 3 1 1 1 . [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2
- 3 1 1 1 [[[neg] dupdip sqr 4] dipd * * - sqrt pm] . dip 2 * [truediv] cons app2
- 3 1 1 . [[neg] dupdip sqr 4] dipd * * - sqrt pm 1 2 * [truediv] cons app2
- 3 1 1 [[neg] dupdip sqr 4] . dipd * * - sqrt pm 1 2 * [truediv] cons app2
- 3 . [neg] dupdip sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- 3 [neg] . dupdip sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- 3 . neg 3 sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 . 3 sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 3 . sqr 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 3 . dup mul 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 3 3 . mul 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 . 4 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 . 1 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 1 . 1 * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 1 1 . * * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 1 . * - sqrt pm 1 2 * [truediv] cons app2
- -3 9 4 . - sqrt pm 1 2 * [truediv] cons app2
- -3 5 . sqrt pm 1 2 * [truediv] cons app2
- -3 2.23606797749979 . pm 1 2 * [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 . 1 2 * [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 1 . 2 * [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 1 2 . * [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 2 . [truediv] cons app2
- -0.7639320225002102 -5.23606797749979 2 [truediv] . cons app2
- -0.7639320225002102 -5.23606797749979 [2 truediv] . app2
- [-0.7639320225002102] [2 truediv] . infra first [-5.23606797749979] [2 truediv] infra first
- -0.7639320225002102 . 2 truediv [] swaack first [-5.23606797749979] [2 truediv] infra first
- -0.7639320225002102 2 . truediv [] swaack first [-5.23606797749979] [2 truediv] infra first
- -0.3819660112501051 . [] swaack first [-5.23606797749979] [2 truediv] infra first
- -0.3819660112501051 [] . swaack first [-5.23606797749979] [2 truediv] infra first
- [-0.3819660112501051] . first [-5.23606797749979] [2 truediv] infra first
- -0.3819660112501051 . [-5.23606797749979] [2 truediv] infra first
- -0.3819660112501051 [-5.23606797749979] . [2 truediv] infra first
- -0.3819660112501051 [-5.23606797749979] [2 truediv] . infra first
- -5.23606797749979 . 2 truediv [-0.3819660112501051] swaack first
- -5.23606797749979 2 . truediv [-0.3819660112501051] swaack first
- -2.618033988749895 . [-0.3819660112501051] swaack first
- -2.618033988749895 [-0.3819660112501051] . swaack first
- -0.3819660112501051 [-2.618033988749895] . first
- -0.3819660112501051 -2.618033988749895 .
+ . -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 .
diff --git a/docs/sphinx_docs/notebooks/Recursion_Combinators.rst b/docs/sphinx_docs/notebooks/Recursion_Combinators.rst
new file mode 100644
index 0000000..b4dc1a7
--- /dev/null
+++ b/docs/sphinx_docs/notebooks/Recursion_Combinators.rst
@@ -0,0 +1,695 @@
+
+.. code:: ipython2
+
+ from notebook_preamble import D, DefinitionWrapper, J, V, define
+
+Recursive 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 `__
+------------------------------------------------------------------------------------
+
+A
+`hylomorphism `__
+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" `__
+
+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 `__
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Let's 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')
+
+Let's 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
+generator's 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 you'll 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 `__
+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" `__
+
+::
+
+ (|...|) [(...)] [<...>]
+
+I think they are having slightly too much fun with the symbols. However,
+"Too much is always better than not enough."
diff --git a/docs/sphinx_docs/notebooks/Types.rst b/docs/sphinx_docs/notebooks/Types.rst
new file mode 100644
index 0000000..971fdfc
--- /dev/null
+++ b/docs/sphinx_docs/notebooks/Types.rst
@@ -0,0 +1,2206 @@
+
+Type Inference
+==============
+
+Pöial's Rules
+-------------
+
+`"Typing Tools for Typeless Stack Languages" by Jaanus
+Pöial `__
+
+::
+
+ @INPROCEEDINGS{Pöial06typingtools,
+ author = {Jaanus Pöial},
+ title = {Typing tools for typeless stack languages},
+ booktitle = {In 23rd Euro-Forth Conference},
+ year = {2006},
+ pages = {40--46}
+ }
+
+First Rule
+~~~~~~~~~~
+
+This rule deals with functions (and literals) that put items on the
+stack ``(-- d)``:
+
+::
+
+ (a -- b)∘(-- d)
+ ---------------------
+ (a -- b d)
+
+Second Rule
+~~~~~~~~~~~
+
+This rule deals with functions that consume items from the stack
+``(a --)``:
+
+::
+
+ (a --)∘(c -- d)
+ ---------------------
+ (c a -- d)
+
+Third Rule
+~~~~~~~~~~
+
+The third rule is actually two rules. These two rules deal with
+composing functions when the second one will consume one of items the
+first one produces. The two types must be *unified* or a type conflict
+declared.
+
+::
+
+ (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == t[k] == u[j]
+ ^
+
+ (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == u[k] == u[j]
+
+Examples
+--------
+
+Let's work through some examples by hand to develop an intuition for the
+algorithm.
+
+There's a function in one of the other notebooks.
+
+::
+
+ F == pop swap roll< rest rest cons cons
+
+It's all "stack chatter" and list manipulation so we should be able to
+deduce its type.
+
+Stack Effect Comments
+~~~~~~~~~~~~~~~~~~~~~
+
+Joy function types will be represented by Forth-style stack effect
+comments. I'm going to use numbers instead of names to keep track of the
+stack arguments. (A little bit like `De Bruijn
+index `__, at least it
+reminds me of them):
+
+::
+
+ pop (1 --)
+
+ swap (1 2 -- 2 1)
+
+ roll< (1 2 3 -- 2 3 1)
+
+These commands alter the stack but don't "look at" the values so these
+numbers represent an "Any type".
+
+``pop swap``
+~~~~~~~~~~~~
+
+::
+
+ (1 --) (1 2 -- 2 1)
+
+Here we encounter a complication. The argument numbers need to be made
+unique among both sides. For this let's change ``pop`` to use 0:
+
+::
+
+ (0 --) (1 2 -- 2 1)
+
+Following the second rule:
+
+::
+
+ (1 2 0 -- 2 1)
+
+``pop∘swap roll<``
+~~~~~~~~~~~~~~~~~~
+
+::
+
+ (1 2 0 -- 2 1) (1 2 3 -- 2 3 1)
+
+Let's re-label them:
+
+::
+
+ (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
+
+Now we follow the rules.
+
+We must unify ``1a`` and ``3b``, and ``2a`` and ``2b``, replacing the
+terms in the forms:
+
+::
+
+ (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
+ w/ {1a: 3b}
+ (3b 2a 0a -- 2a ) (1b 2b -- 2b 3b 1b)
+ w/ {2a: 2b}
+ (3b 2b 0a -- ) (1b -- 2b 3b 1b)
+
+Here we must apply the second rule:
+
+::
+
+ (3b 2b 0a --) (1b -- 2b 3b 1b)
+ -----------------------------------
+ (1b 3b 2b 0a -- 2b 3b 1b)
+
+Now we de-label the type, uh, labels:
+
+::
+
+ (1b 3b 2b 0a -- 2b 3b 1b)
+
+ w/ {
+ 1b: 1,
+ 3b: 2,
+ 2b: 3,
+ 0a: 0,
+ }
+
+ (1 2 3 0 -- 3 2 1)
+
+And now we have the stack effect comment for ``pop∘swap∘roll<``.
+
+Compiling ``pop∘swap∘roll<``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The simplest way to "compile" this function would be something like:
+
+.. code:: ipython2
+
+ def poswrd(s, e, d):
+ return roll_down(*swap(*pop(s, e, d)))
+
+However, internally this function would still be allocating tuples
+(stack cells) and doing other unnecesssary work.
+
+Looking ahead for a moment, from the stack effect comment:
+
+::
+
+ (1 2 3 0 -- 3 2 1)
+
+We should be able to directly write out a Python function like:
+
+.. code:: ipython2
+
+ def poswrd(stack):
+ (_, (a, (b, (c, stack)))) = stack
+ return (c, (b, (a, stack)))
+
+This eliminates the internal work of the first version. Because this
+function only rearranges the stack and doesn't do any actual processing
+on the stack items themselves all the information needed to implement it
+is in the stack effect comment.
+
+Functions on Lists
+~~~~~~~~~~~~~~~~~~
+
+These are slightly tricky.
+
+::
+
+ rest ( [1 ...] -- [...] )
+
+ cons ( 1 [...] -- [1 ...] )
+
+``pop∘swap∘roll< rest``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ (1 2 3 0 -- 3 2 1) ([1 ...] -- [...])
+
+Re-label (instead of adding left and right tags I'm just taking the next
+available index number for the right-side stack effect comment):
+
+::
+
+ (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
+
+Unify and update:
+
+::
+
+ (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
+ w/ {1: [4 ...]}
+ ([4 ...] 2 3 0 -- 3 2 ) ( -- [...])
+
+Apply the first rule:
+
+::
+
+ ([4 ...] 2 3 0 -- 3 2) (-- [...])
+ ---------------------------------------
+ ([4 ...] 2 3 0 -- 3 2 [...])
+
+And there we are.
+
+``pop∘swap∘roll<∘rest rest``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Let's do it again.
+
+::
+
+ ([4 ...] 2 3 0 -- 3 2 [...]) ([1 ...] -- [...])
+
+Re-label (the tails of the lists on each side each get their own label):
+
+::
+
+ ([4 .0.] 2 3 0 -- 3 2 [.0.]) ([5 .1.] -- [.1.])
+
+Unify and update (note the opening square brackets have been omited in
+the substitution dict, this is deliberate and I'll explain below):
+
+::
+
+ ([4 .0.] 2 3 0 -- 3 2 [.0.] ) ([5 .1.] -- [.1.])
+ w/ { .0.] : 5 .1.] }
+ ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
+
+How do we find ``.0.]`` in ``[4 .0.]`` and replace it with ``5 .1.]``
+getting the result ``[4 5 .1.]``? This might seem hard, but because the
+underlying structure of the Joy list is a cons-list in Python it's
+actually pretty easy. I'll explain below.
+
+Next we unify and find our two terms are the same already: ``[5 .1.]``:
+
+::
+
+ ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
+
+Giving us:
+
+::
+
+ ([4 5 .1.] 2 3 0 -- 3 2) (-- [.1.])
+
+From here we apply the first rule and get:
+
+::
+
+ ([4 5 .1.] 2 3 0 -- 3 2 [.1.])
+
+Cleaning up the labels:
+
+::
+
+ ([4 5 ...] 2 3 1 -- 3 2 [...])
+
+This is the stack effect of ``pop∘swap∘roll<∘rest∘rest``.
+
+``pop∘swap∘roll<∘rest∘rest cons``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ ([4 5 ...] 2 3 1 -- 3 2 [...]) (1 [...] -- [1 ...])
+
+Re-label:
+
+::
+
+ ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
+
+Unify:
+
+::
+
+ ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
+ w/ { .1.] : .2.] }
+ ([4 5 .2.] 2 3 1 -- 3 2 ) (6 -- [6 .2.])
+ w/ {2: 6}
+ ([4 5 .2.] 6 3 1 -- 3 ) ( -- [6 .2.])
+
+First rule:
+
+::
+
+ ([4 5 .2.] 6 3 1 -- 3 [6 .2.])
+
+Re-label:
+
+::
+
+ ([4 5 ...] 2 3 1 -- 3 [2 ...])
+
+Done.
+
+``pop∘swap∘roll<∘rest∘rest∘cons cons``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One more time.
+
+::
+
+ ([4 5 ...] 2 3 1 -- 3 [2 ...]) (1 [...] -- [1 ...])
+
+Re-label:
+
+::
+
+ ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.])
+
+Unify:
+
+::
+
+ ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.] )
+ w/ { .2.] : 2 .1.] }
+ ([4 5 .1.] 2 3 1 -- 3 ) (6 -- [6 2 .1.])
+ w/ {3: 6}
+ ([4 5 .1.] 2 6 1 -- ) ( -- [6 2 .1.])
+
+First or second rule:
+
+::
+
+ ([4 5 .1.] 2 6 1 -- [6 2 .1.])
+
+Clean up the labels:
+
+::
+
+ ([4 5 ...] 2 3 1 -- [3 2 ...])
+
+And there you have it, the stack effect for
+``pop∘swap∘roll<∘rest∘rest∘cons∘cons``.
+
+::
+
+ ([4 5 ...] 2 3 1 -- [3 2 ...])
+
+From this stack effect comment it should be possible to construct the
+following Python code:
+
+.. code:: ipython2
+
+ def F(stack):
+ (_, (d, (c, ((a, (b, S0)), stack)))) = stack
+ return (d, (c, S0)), stack
+
+Implementation
+--------------
+
+Representing Stack Effect Comments in Python
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+I'm going to use pairs of tuples of type descriptors, which will be
+integers or tuples of type descriptors:
+
+.. code:: ipython2
+
+ roll_dn = (1, 2, 3), (2, 3, 1)
+
+ pop = (1,), ()
+
+ swap = (1, 2), (2, 1)
+
+``compose()``
+~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+ def compose(f, g):
+
+ (f_in, f_out), (g_in, g_out) = f, g
+
+ # First rule.
+ #
+ # (a -- b) (-- d)
+ # ---------------------
+ # (a -- b d)
+
+ if not g_in:
+
+ fg_in, fg_out = f_in, f_out + g_out
+
+ # Second rule.
+ #
+ # (a --) (c -- d)
+ # ---------------------
+ # (c a -- d)
+
+ elif not f_out:
+
+ fg_in, fg_out = g_in + f_in, g_out
+
+ else: # Unify, update, recur.
+
+ fo, gi = f_out[-1], g_in[-1]
+
+ s = unify(gi, fo)
+
+ if s == False: # s can also be the empty dict, which is ok.
+ raise TypeError('Cannot unify %r and %r.' % (fo, gi))
+
+ f_g = (f_in, f_out[:-1]), (g_in[:-1], g_out)
+
+ if s: f_g = update(s, f_g)
+
+ fg_in, fg_out = compose(*f_g)
+
+ return fg_in, fg_out
+
+``unify()``
+~~~~~~~~~~~
+
+.. code:: ipython2
+
+ def unify(u, v, s=None):
+ if s is None:
+ s = {}
+
+ if u == v:
+ return s
+
+ if isinstance(u, int):
+ s[u] = v
+ return s
+
+ if isinstance(v, int):
+ s[v] = u
+ return s
+
+ return False
+
+``update()``
+~~~~~~~~~~~~
+
+.. code:: ipython2
+
+ def update(s, term):
+ if not isinstance(term, tuple):
+ return s.get(term, term)
+ return tuple(update(s, inner) for inner in term)
+
+``relabel()``
+~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+ def relabel(left, right):
+ return left, _1000(right)
+
+ def _1000(right):
+ if not isinstance(right, tuple):
+ return 1000 + right
+ return tuple(_1000(n) for n in right)
+
+ relabel(pop, swap)
+
+
+
+
+.. parsed-literal::
+
+ (((1,), ()), ((1001, 1002), (1002, 1001)))
+
+
+
+``delabel()``
+~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+ def delabel(f):
+ s = {u: i for i, u in enumerate(sorted(_unique(f)))}
+ return update(s, f)
+
+ def _unique(f, seen=None):
+ if seen is None:
+ seen = set()
+ if not isinstance(f, tuple):
+ seen.add(f)
+ else:
+ for inner in f:
+ _unique(inner, seen)
+ return seen
+
+ delabel(relabel(pop, swap))
+
+
+
+
+.. parsed-literal::
+
+ (((0,), ()), ((1, 2), (2, 1)))
+
+
+
+``C()``
+~~~~~~~
+
+At last we put it all together in a function ``C()`` that accepts two
+stack effect comments and returns their composition (or raises and
+exception if they can't be composed due to type conflicts.)
+
+.. code:: ipython2
+
+ def C(f, g):
+ f, g = relabel(f, g)
+ fg = compose(f, g)
+ return delabel(fg)
+
+Let's try it out.
+
+.. code:: ipython2
+
+ C(pop, swap)
+
+
+
+
+.. parsed-literal::
+
+ ((1, 2, 0), (2, 1))
+
+
+
+.. code:: ipython2
+
+ C(C(pop, swap), roll_dn)
+
+
+
+
+.. parsed-literal::
+
+ ((3, 1, 2, 0), (2, 1, 3))
+
+
+
+.. code:: ipython2
+
+ C(swap, roll_dn)
+
+
+
+
+.. parsed-literal::
+
+ ((2, 0, 1), (1, 0, 2))
+
+
+
+.. code:: ipython2
+
+ C(pop, C(swap, roll_dn))
+
+
+
+
+.. parsed-literal::
+
+ ((3, 1, 2, 0), (2, 1, 3))
+
+
+
+.. code:: ipython2
+
+ poswrd = reduce(C, (pop, swap, roll_dn))
+ poswrd
+
+
+
+
+.. parsed-literal::
+
+ ((3, 1, 2, 0), (2, 1, 3))
+
+
+
+List Functions
+~~~~~~~~~~~~~~
+
+Here's that trick to represent functions like ``rest`` and ``cons`` that
+manipulate lists. We use a cons-list of tuples and give the tails their
+own numbers. Then everything above already works.
+
+.. code:: ipython2
+
+ rest = ((1, 2),), (2,)
+
+ cons = (1, 2), ((1, 2),)
+
+.. code:: ipython2
+
+ C(poswrd, rest)
+
+
+
+
+.. parsed-literal::
+
+ (((3, 4), 1, 2, 0), (2, 1, 4))
+
+
+
+Compare this to the stack effect comment we wrote above:
+
+::
+
+ (( (3, 4), 1, 2, 0 ), ( 2, 1, 4 ))
+ ( [4 ...] 2 3 0 -- 3 2 [...])
+
+The translation table, if you will, would be:
+
+::
+
+ {
+ 3: 4,
+ 4: ...],
+ 1: 2,
+ 2: 3,
+ 0: 0,
+ }
+
+.. code:: ipython2
+
+ F = reduce(C, (pop, swap, roll_dn, rest, rest, cons, cons))
+
+ F
+
+
+
+
+.. parsed-literal::
+
+ (((3, (4, 5)), 1, 2, 0), ((2, (1, 5)),))
+
+
+
+Compare with the stack effect comment and you can see it works fine:
+
+::
+
+ ([4 5 ...] 2 3 1 -- [3 2 ...])
+
+Dealing with ``cons`` and ``uncons``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+However, if we try to compose e.g. ``cons`` and ``uncons`` it won't
+work:
+
+.. code:: ipython2
+
+ uncons = ((1, 2),), (1, 2)
+
+.. code:: ipython2
+
+ try:
+ C(cons, uncons)
+ except Exception, e:
+ print e
+
+
+.. parsed-literal::
+
+ Cannot unify (1, 2) and (1001, 1002).
+
+
+``unify()`` version 2
+^^^^^^^^^^^^^^^^^^^^^
+
+The problem is that the ``unify()`` function as written doesn't handle
+the case when both terms are tuples. We just have to add a clause to
+deal with this recursively:
+
+.. code:: ipython2
+
+ def unify(u, v, s=None):
+ if s is None:
+ s = {}
+ else:
+ u = update(s, u)
+ v = update(s, v)
+
+ if u == v:
+ return s
+
+ if isinstance(u, int):
+ s[u] = v
+ return s
+
+ if isinstance(v, int):
+ s[v] = u
+ return s
+
+ if isinstance(u, tuple) and isinstance(v, tuple):
+ if len(u) != len(v) != 2:
+ raise ValueError(repr((u, v)))
+ for uu, vv in zip(u, v):
+ s = unify(uu, vv, s)
+ if s == False: # (instead of a substitution dict.)
+ break
+ return s
+
+ return False
+
+.. code:: ipython2
+
+ C(cons, uncons)
+
+
+
+
+.. parsed-literal::
+
+ ((0, 1), (0, 1))
+
+
+
+Compiling
+---------
+
+Now consider the Python function we would like to derive:
+
+.. code:: ipython2
+
+ def F_python(stack):
+ (_, (d, (c, ((a, (b, S0)), stack)))) = stack
+ return (d, (c, S0)), stack
+
+And compare it to the input stack effect comment tuple we just computed:
+
+.. code:: ipython2
+
+ F[0]
+
+
+
+
+.. parsed-literal::
+
+ ((3, (4, 5)), 1, 2, 0)
+
+
+
+The stack-de-structuring tuple has nearly the same form as our input
+stack effect comment tuple, just in the reverse order:
+
+::
+
+ (_, (d, (c, ((a, (b, S0)), stack))))
+
+Remove the punctuation:
+
+::
+
+ _ d c (a, (b, S0))
+
+Reverse the order and compare:
+
+::
+
+ (a, (b, S0)) c d _
+ ((3, (4, 5 )), 1, 2, 0)
+
+Eh?
+
+And the return tuple
+
+.. code:: ipython2
+
+ F[1]
+
+
+
+
+.. parsed-literal::
+
+ ((2, (1, 5)),)
+
+
+
+is similar to the output stack effect comment tuple:
+
+::
+
+ ((d, (c, S0)), stack)
+ ((2, (1, 5 )), )
+
+This should make it pretty easy to write a Python function that accepts
+the stack effect comment tuples and returns a new Python function
+(either as a string of code or a function object ready to use) that
+performs the semantics of that Joy function (described by the stack
+effect.)
+
+Python Identifiers
+~~~~~~~~~~~~~~~~~~
+
+We want to substitute Python identifiers for the integers. I'm going to
+repurpose ``joy.parser.Symbol`` class for this:
+
+.. code:: ipython2
+
+ from collections import defaultdict
+ from joy.parser import Symbol
+
+
+ def _names_for():
+ I = iter(xrange(1000))
+ return lambda: Symbol('a%i' % next(I))
+
+
+ def identifiers(term, s=None):
+ if s is None:
+ s = defaultdict(_names_for())
+ if isinstance(term, int):
+ return s[term]
+ return tuple(identifiers(inner, s) for inner in term)
+
+``doc_from_stack_effect()``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As a convenience I've implemented a function to convert the Python stack
+effect comment tuples to reasonable text format. There are some details
+in how this code works that related to stuff later in the notebook, so
+you should skip it for now and read it later if you're interested.
+
+.. code:: ipython2
+
+ def doc_from_stack_effect(inputs, outputs):
+ return '(%s--%s)' % (
+ ' '.join(map(_to_str, inputs + ('',))),
+ ' '.join(map(_to_str, ('',) + outputs))
+ )
+
+
+ def _to_str(term):
+ if not isinstance(term, tuple):
+ try:
+ t = term.prefix == 's'
+ except AttributeError:
+ return str(term)
+ return '[.%i.]' % term.number if t else str(term)
+
+ a = []
+ while term and isinstance(term, tuple):
+ item, term = term
+ a.append(_to_str(item))
+
+ try:
+ n = term.number
+ except AttributeError:
+ n = term
+ else:
+ if term.prefix != 's':
+ raise ValueError('Stack label: %s' % (term,))
+
+ a.append('.%s.' % (n,))
+ return '[%s]' % ' '.join(a)
+
+``compile_()``
+~~~~~~~~~~~~~~
+
+Now we can write a compiler function to emit Python source code. (The
+underscore suffix distiguishes it from the built-in ``compile()``
+function.)
+
+.. code:: ipython2
+
+ def compile_(name, f, doc=None):
+ if doc is None:
+ doc = doc_from_stack_effect(*f)
+ inputs, outputs = identifiers(f)
+ i = o = Symbol('stack')
+ for term in inputs:
+ i = term, i
+ for term in outputs:
+ o = term, o
+ return '''def %s(stack):
+ """%s"""
+ %s = stack
+ return %s''' % (name, doc, i, o)
+
+Here it is in action:
+
+.. code:: ipython2
+
+ source = compile_('F', F)
+
+ print source
+
+
+.. parsed-literal::
+
+ def F(stack):
+ """([3 4 .5.] 1 2 0 -- [2 1 .5.])"""
+ (a5, (a4, (a3, ((a0, (a1, a2)), stack)))) = stack
+ return ((a4, (a3, a2)), stack)
+
+
+Compare:
+
+.. code:: ipython2
+
+ def F_python(stack):
+ (_, (d, (c, ((a, (b, S0)), stack)))) = stack
+ return ((d, (c, S0)), stack)
+
+Next steps:
+
+.. code:: ipython2
+
+ L = {}
+
+ eval(compile(source, '__main__', 'single'), {}, L)
+
+ L['F']
+
+
+
+
+.. parsed-literal::
+
+
+
+
+
+Let's try it out:
+
+.. code:: ipython2
+
+ from notebook_preamble import D, J, V
+ from joy.library import SimpleFunctionWrapper
+
+.. code:: ipython2
+
+ D['F'] = SimpleFunctionWrapper(L['F'])
+
+.. code:: ipython2
+
+ J('[4 5 ...] 2 3 1 F')
+
+
+.. parsed-literal::
+
+ [3 2 ...]
+
+
+With this, we have a partial Joy compiler that works on the subset of
+Joy functions that manipulate stacks (both what I call "stack chatter"
+and the ones that manipulate stacks on the stack.)
+
+I'm probably going to modify the definition wrapper code to detect
+definitions that can be compiled by this partial compiler and do it
+automatically. It might be a reasonable idea to detect sequences of
+compilable functions in definitions that have uncompilable functions in
+them and just compile those. However, if your library is well-factored
+this might be less helpful.
+
+Compiling Library Functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We can use ``compile_()`` to generate many primitives in the library
+from their stack effect comments:
+
+.. code:: ipython2
+
+ def defs():
+
+ roll_down = (1, 2, 3), (2, 3, 1)
+
+ roll_up = (1, 2, 3), (3, 1, 2)
+
+ pop = (1,), ()
+
+ swap = (1, 2), (2, 1)
+
+ rest = ((1, 2),), (2,)
+
+ rrest = C(rest, rest)
+
+ cons = (1, 2), ((1, 2),)
+
+ uncons = ((1, 2),), (1, 2)
+
+ swons = C(swap, cons)
+
+ return locals()
+
+.. code:: ipython2
+
+ for name, stack_effect_comment in sorted(defs().items()):
+ print
+ print compile_(name, stack_effect_comment)
+ print
+
+
+.. parsed-literal::
+
+
+ def cons(stack):
+ """(1 2 -- [1 .2.])"""
+ (a1, (a0, stack)) = stack
+ return ((a0, a1), stack)
+
+
+ def pop(stack):
+ """(1 --)"""
+ (a0, stack) = stack
+ return stack
+
+
+ def rest(stack):
+ """([1 .2.] -- 2)"""
+ ((a0, a1), stack) = stack
+ return (a1, stack)
+
+
+ def roll_down(stack):
+ """(1 2 3 -- 2 3 1)"""
+ (a2, (a1, (a0, stack))) = stack
+ return (a0, (a2, (a1, stack)))
+
+
+ def roll_up(stack):
+ """(1 2 3 -- 3 1 2)"""
+ (a2, (a1, (a0, stack))) = stack
+ return (a1, (a0, (a2, stack)))
+
+
+ def rrest(stack):
+ """([0 1 .2.] -- 2)"""
+ ((a0, (a1, a2)), stack) = stack
+ return (a2, stack)
+
+
+ def swap(stack):
+ """(1 2 -- 2 1)"""
+ (a1, (a0, stack)) = stack
+ return (a0, (a1, stack))
+
+
+ def swons(stack):
+ """(0 1 -- [1 .0.])"""
+ (a1, (a0, stack)) = stack
+ return ((a1, a0), stack)
+
+
+ def uncons(stack):
+ """([1 .2.] -- 1 2)"""
+ ((a0, a1), stack) = stack
+ return (a1, (a0, stack))
+
+
+
+Types and Subtypes of Arguments
+-------------------------------
+
+So far we have dealt with types of functions, those dealing with simple
+stack manipulation. Let's extend our machinery to deal with types of
+arguments.
+
+"Number" Type
+~~~~~~~~~~~~~
+
+Consider the definition of ``sqr``:
+
+::
+
+ sqr == dup mul
+
+The ``dup`` function accepts one *anything* and returns two of that:
+
+::
+
+ dup (1 -- 1 1)
+
+And ``mul`` accepts two "numbers" (we're ignoring ints vs. floats vs.
+complex, etc., for now) and returns just one:
+
+::
+
+ mul (n n -- n)
+
+So we're composing:
+
+::
+
+ (1 -- 1 1)∘(n n -- n)
+
+The rules say we unify 1 with ``n``:
+
+::
+
+ (1 -- 1 1)∘(n n -- n)
+ --------------------------- w/ {1: n}
+ (1 -- 1 )∘(n -- n)
+
+This involves detecting that "Any type" arguments can accept "numbers".
+If we were composing these functions the other way round this is still
+the case:
+
+::
+
+ (n n -- n)∘(1 -- 1 1)
+ --------------------------- w/ {1: n}
+ (n n -- )∘( -- n n)
+
+The important thing here is that the mapping is going the same way in
+both cases, from the "any" integer to the number
+
+Distinguishing Numbers
+~~~~~~~~~~~~~~~~~~~~~~
+
+We should also mind that the number that ``mul`` produces is not
+(necessarily) the same as either of its inputs, which are not
+(necessarily) the same as each other:
+
+::
+
+ mul (n2 n1 -- n3)
+
+
+ (1 -- 1 1)∘(n2 n1 -- n3)
+ -------------------------------- w/ {1: n2}
+ (n2 -- n2 )∘(n2 -- n3)
+
+
+ (n2 n1 -- n3)∘(1 -- 1 1 )
+ -------------------------------- w/ {1: n3}
+ (n2 n1 -- )∘( -- n3 n3)
+
+Distinguishing Types
+~~~~~~~~~~~~~~~~~~~~
+
+So we need separate domains of "any" numbers and "number" numbers, and
+we need to be able to ask the order of these domains. Now the notes on
+the right side of rule three make more sense, eh?
+
+::
+
+ (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == t[k] == u[j]
+ ^
+
+ (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == u[k] == u[j]
+
+The indices ``i``, ``k``, and ``j`` are the number part of our labels
+and ``t`` and ``u`` are the domains.
+
+By creative use of Python's "double underscore" methods we can define a
+Python class hierarchy of Joy types and use the ``issubclass()`` method
+to establish domain ordering, as well as other handy behaviour that will
+make it fairly easy to reuse most of the code above.
+
+.. code:: ipython2
+
+ class AnyJoyType(object):
+
+ prefix = 'a'
+
+ def __init__(self, number):
+ self.number = number
+
+ def __repr__(self):
+ return self.prefix + str(self.number)
+
+ def __eq__(self, other):
+ return (
+ isinstance(other, self.__class__)
+ and other.prefix == self.prefix
+ and other.number == self.number
+ )
+
+ def __ge__(self, other):
+ return issubclass(other.__class__, self.__class__)
+
+ def __add__(self, other):
+ return self.__class__(self.number + other)
+ __radd__ = __add__
+
+ def __hash__(self):
+ return hash(repr(self))
+
+
+ class NumberJoyType(AnyJoyType): prefix = 'n'
+ class FloatJoyType(NumberJoyType): prefix = 'f'
+ class IntJoyType(FloatJoyType): prefix = 'i'
+
+
+ class StackJoyType(AnyJoyType):
+ prefix = 's'
+
+
+ _R = range(10)
+ A = map(AnyJoyType, _R)
+ N = map(NumberJoyType, _R)
+ S = map(StackJoyType, _R)
+
+Mess with it a little:
+
+.. code:: ipython2
+
+ from itertools import permutations
+
+"Any" types can be specialized to numbers and stacks, but not vice
+versa:
+
+.. code:: ipython2
+
+ for a, b in permutations((A[0], N[0], S[0]), 2):
+ print a, '>=', b, '->', a >= b
+
+
+.. parsed-literal::
+
+ a0 >= n0 -> True
+ a0 >= s0 -> True
+ n0 >= a0 -> False
+ n0 >= s0 -> False
+ s0 >= a0 -> False
+ s0 >= n0 -> False
+
+
+Our crude `Numerical
+Tower `__ of *numbers* >
+*floats* > *integers* works as well (but we're not going to use it yet):
+
+.. code:: ipython2
+
+ for a, b in permutations((A[0], N[0], FloatJoyType(0), IntJoyType(0)), 2):
+ print a, '>=', b, '->', a >= b
+
+
+.. parsed-literal::
+
+ a0 >= n0 -> True
+ a0 >= f0 -> True
+ a0 >= i0 -> True
+ n0 >= a0 -> False
+ n0 >= f0 -> True
+ n0 >= i0 -> True
+ f0 >= a0 -> False
+ f0 >= n0 -> False
+ f0 >= i0 -> True
+ i0 >= a0 -> False
+ i0 >= n0 -> False
+ i0 >= f0 -> False
+
+
+Typing ``sqr``
+~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+ dup = (A[1],), (A[1], A[1])
+
+ mul = (N[1], N[2]), (N[3],)
+
+.. code:: ipython2
+
+ dup
+
+
+
+
+.. parsed-literal::
+
+ ((a1,), (a1, a1))
+
+
+
+.. code:: ipython2
+
+ mul
+
+
+
+
+.. parsed-literal::
+
+ ((n1, n2), (n3,))
+
+
+
+Modifying the Inferencer
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Re-labeling still works fine:
+
+.. code:: ipython2
+
+ foo = relabel(dup, mul)
+
+ foo
+
+
+
+
+.. parsed-literal::
+
+ (((a1,), (a1, a1)), ((n1001, n1002), (n1003,)))
+
+
+
+``delabel()`` version 2
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The ``delabel()`` function needs an overhaul. It now has to keep track
+of how many labels of each domain it has "seen".
+
+.. code:: ipython2
+
+ from collections import Counter
+
+
+ def delabel(f, seen=None, c=None):
+ if seen is None:
+ assert c is None
+ seen, c = {}, Counter()
+
+ try:
+ return seen[f]
+ except KeyError:
+ pass
+
+ if not isinstance(f, tuple):
+ seen[f] = f.__class__(c[f.prefix])
+ c[f.prefix] += 1
+ return seen[f]
+
+ return tuple(delabel(inner, seen, c) for inner in f)
+
+.. code:: ipython2
+
+ delabel(foo)
+
+
+
+
+.. parsed-literal::
+
+ (((a0,), (a0, a0)), ((n0, n1), (n2,)))
+
+
+
+``unify()`` version 3
+^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: ipython2
+
+ def unify(u, v, s=None):
+ if s is None:
+ s = {}
+ else:
+ u = update(s, u)
+ v = update(s, v)
+
+ if u == v:
+ return s
+
+ if isinstance(u, AnyJoyType) and isinstance(v, AnyJoyType):
+ if u >= v:
+ s[u] = v
+ return s
+ if v >= u:
+ s[v] = u
+ return s
+ raise ValueError('Cannot unify %r and %r.' % (u, v))
+
+ if isinstance(u, tuple) and isinstance(v, tuple):
+ if len(u) != len(v) != 2:
+ raise ValueError(repr((u, v)))
+ for uu, vv in zip(u, v):
+ s = unify(uu, vv, s)
+ if s == False: # (instead of a substitution dict.)
+ break
+ return s
+
+ if isinstance(v, tuple):
+ if not stacky(u):
+ raise ValueError('Cannot unify %r and %r.' % (u, v))
+ s[u] = v
+ return s
+
+ if isinstance(u, tuple):
+ if not stacky(v):
+ raise ValueError('Cannot unify %r and %r.' % (v, u))
+ s[v] = u
+ return s
+
+ return False
+
+
+ def stacky(thing):
+ return thing.__class__ in {AnyJoyType, StackJoyType}
+
+Rewrite the stack effect comments:
+
+.. code:: ipython2
+
+ def defs():
+
+ roll_down = (A[1], A[2], A[3]), (A[2], A[3], A[1])
+
+ roll_up = (A[1], A[2], A[3]), (A[3], A[1], A[2])
+
+ pop = (A[1],), ()
+
+ popop = (A[2], A[1],), ()
+
+ popd = (A[2], A[1],), (A[1],)
+
+ popdd = (A[3], A[2], A[1],), (A[2], A[1],)
+
+ swap = (A[1], A[2]), (A[2], A[1])
+
+ rest = ((A[1], S[1]),), (S[1],)
+
+ rrest = C(rest, rest)
+
+ cons = (A[1], S[1]), ((A[1], S[1]),)
+
+ ccons = C(cons, cons)
+
+ uncons = ((A[1], S[1]),), (A[1], S[1])
+
+ swons = C(swap, cons)
+
+ dup = (A[1],), (A[1], A[1])
+
+ dupd = (A[2], A[1]), (A[2], A[2], A[1])
+
+ mul = (N[1], N[2]), (N[3],)
+
+ sqrt = C(dup, mul)
+
+ first = ((A[1], S[1]),), (A[1],)
+
+ second = C(rest, first)
+
+ third = C(rest, second)
+
+ tuck = (A[2], A[1]), (A[1], A[2], A[1])
+
+ over = (A[2], A[1]), (A[2], A[1], A[2])
+
+ succ = pred = (N[1],), (N[2],)
+
+ divmod_ = pm = (N[2], N[1]), (N[4], N[3])
+
+ return locals()
+
+.. code:: ipython2
+
+ DEFS = defs()
+
+.. code:: ipython2
+
+ for name, stack_effect_comment in sorted(DEFS.items()):
+ print name, '=', doc_from_stack_effect(*stack_effect_comment)
+
+
+.. parsed-literal::
+
+ ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+ cons = (a1 [.1.] -- [a1 .1.])
+ divmod_ = (n2 n1 -- n4 n3)
+ dup = (a1 -- a1 a1)
+ dupd = (a2 a1 -- a2 a2 a1)
+ first = ([a1 .1.] -- a1)
+ mul = (n1 n2 -- n3)
+ 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 --)
+ pred = (n1 -- n2)
+ rest = ([a1 .1.] -- [.1.])
+ roll_down = (a1 a2 a3 -- a2 a3 a1)
+ roll_up = (a1 a2 a3 -- a3 a1 a2)
+ rrest = ([a0 a1 .0.] -- [.0.])
+ second = ([a0 a1 .0.] -- a1)
+ sqrt = (n0 -- n1)
+ succ = (n1 -- n2)
+ swap = (a1 a2 -- a2 a1)
+ swons = ([.0.] a0 -- [a0 .0.])
+ third = ([a0 a1 a2 .0.] -- a2)
+ tuck = (a2 a1 -- a1 a2 a1)
+ uncons = ([a1 .1.] -- a1 [.1.])
+
+
+.. code:: ipython2
+
+ globals().update(DEFS)
+
+Compose ``dup`` and ``mul``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code:: ipython2
+
+ C(dup, mul)
+
+
+
+
+.. parsed-literal::
+
+ ((n0,), (n1,))
+
+
+
+Revisit the ``F`` function, works fine.
+
+.. code:: ipython2
+
+ F = reduce(C, (pop, swap, roll_down, rest, rest, cons, cons))
+ F
+
+
+
+
+.. parsed-literal::
+
+ (((a0, (a1, s0)), a2, a3, a4), ((a3, (a2, s0)),))
+
+
+
+.. code:: ipython2
+
+ print doc_from_stack_effect(*F)
+
+
+.. parsed-literal::
+
+ ([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])
+
+
+Some otherwise inefficient functions are no longer to be feared. We can
+also get the effect of combinators in some limited cases.
+
+.. code:: ipython2
+
+ def neato(*funcs):
+ print doc_from_stack_effect(*reduce(C, funcs))
+
+.. code:: ipython2
+
+ # e.g. [swap] dip
+ neato(roll_up, swap, roll_down)
+
+
+.. parsed-literal::
+
+ (a0 a1 a2 -- a1 a0 a2)
+
+
+.. code:: ipython2
+
+ # e.g. [popop] dip
+ neato(popdd, roll_down, pop)
+
+
+.. parsed-literal::
+
+ (a0 a1 a2 a3 -- a2 a3)
+
+
+.. code:: ipython2
+
+ # Reverse the order of the top three items.
+ neato(roll_up, swap)
+
+
+.. parsed-literal::
+
+ (a0 a1 a2 -- a2 a1 a0)
+
+
+``compile_()`` version 2
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Because the type labels represent themselves as valid Python identifiers
+the ``compile_()`` function doesn't need to generate them anymore:
+
+.. code:: ipython2
+
+ def compile_(name, f, doc=None):
+ inputs, outputs = f
+ if doc is None:
+ doc = doc_from_stack_effect(inputs, outputs)
+ i = o = Symbol('stack')
+ for term in inputs:
+ i = term, i
+ for term in outputs:
+ o = term, o
+ return '''def %s(stack):
+ """%s"""
+ %s = stack
+ return %s''' % (name, doc, i, o)
+
+.. code:: ipython2
+
+ print compile_('F', F)
+
+
+.. parsed-literal::
+
+ def F(stack):
+ """([a0 a1 .0.] a2 a3 a4 -- [a3 a2 .0.])"""
+ (a4, (a3, (a2, ((a0, (a1, s0)), stack)))) = stack
+ return ((a3, (a2, s0)), stack)
+
+
+But it cannot magically create new functions that involve e.g. math and
+such. Note that this is *not* a ``sqr`` function implementation:
+
+.. code:: ipython2
+
+ print compile_('sqr', C(dup, mul))
+
+
+.. parsed-literal::
+
+ def sqr(stack):
+ """(n0 -- n1)"""
+ (n0, stack) = stack
+ return (n1, stack)
+
+
+``compilable()``
+^^^^^^^^^^^^^^^^
+
+The functions that *can* be compiled are the ones that have only
+``AnyJoyType`` and ``StackJoyType`` labels in their stack effect
+comments. We can write a function to check that:
+
+.. code:: ipython2
+
+ from itertools import imap
+
+
+ def compilable(f):
+ return isinstance(f, tuple) and all(imap(compilable, f)) or stacky(f)
+
+.. code:: ipython2
+
+ for name, stack_effect_comment in sorted(defs().items()):
+ if compilable(stack_effect_comment):
+ print name, '=', doc_from_stack_effect(*stack_effect_comment)
+
+
+.. parsed-literal::
+
+ ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+ cons = (a1 [.1.] -- [a1 .1.])
+ dup = (a1 -- a1 a1)
+ dupd = (a2 a1 -- a2 a2 a1)
+ first = ([a1 .1.] -- a1)
+ over = (a2 a1 -- a2 a1 a2)
+ pop = (a1 --)
+ popd = (a2 a1 -- a1)
+ popdd = (a3 a2 a1 -- a2 a1)
+ popop = (a2 a1 --)
+ rest = ([a1 .1.] -- [.1.])
+ roll_down = (a1 a2 a3 -- a2 a3 a1)
+ roll_up = (a1 a2 a3 -- a3 a1 a2)
+ rrest = ([a0 a1 .0.] -- [.0.])
+ second = ([a0 a1 .0.] -- a1)
+ swap = (a1 a2 -- a2 a1)
+ swons = ([.0.] a0 -- [a0 .0.])
+ third = ([a0 a1 a2 .0.] -- a2)
+ tuck = (a2 a1 -- a1 a2 a1)
+ uncons = ([a1 .1.] -- a1 [.1.])
+
+
+Functions that use the Stack
+----------------------------
+
+Consider the ``stack`` function which grabs the whole stack, quotes it,
+and puts it on itself:
+
+::
+
+ stack (... -- ... [...] )
+ stack (... a -- ... a [a ...] )
+ stack (... b a -- ... b a [a b ...])
+
+We would like to represent this in Python somehow. To do this we use a
+simple, elegant trick.
+
+::
+
+ stack S -- ( S, S)
+ stack (a, S) -- ( (a, S), (a, S))
+ stack (a, (b, S)) -- ( (a, (b, S)), (a, (b, S)))
+
+Instead of representing the stack effect comments as a single tuple
+(with N items in it) we use the same cons-list structure to hold the
+sequence and ``unify()`` the whole comments.
+
+``stack∘uncons``
+~~~~~~~~~~~~~~~~
+
+Let's try composing ``stack`` and ``uncons``. We want this result:
+
+::
+
+ stack∘uncons (... a -- ... a a [...])
+
+The stack effects are:
+
+::
+
+ stack = S -- (S, S)
+
+ uncons = ((a, Z), S) -- (Z, (a, S))
+
+Unifying:
+
+::
+
+ S -- (S, S) ∘ ((a, Z), S) -- (Z, (a, S ))
+ w/ { S: (a, Z) }
+ (a, Z) -- ∘ -- (Z, (a, (a, Z)))
+
+So:
+
+::
+
+ stack∘uncons == (a, Z) -- (Z, (a, (a, Z)))
+
+It works.
+
+``stack∘uncons∘uncons``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Let's try ``stack∘uncons∘uncons``:
+
+::
+
+ (a, S ) -- (S, (a, (a, S ))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
+
+ w/ { S: (b, Z) }
+
+ (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
+
+ w/ { S`: (a, (a, (b, Z))) }
+
+ (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), (a, (a, (b, Z)))) -- (Z, (b, (a, (a, (b, Z)))))
+
+ (a, (b, Z)) -- (Z, (b, (a, (a, (b, Z)))))
+
+It works.
+
+``compose()`` version 2
+^^^^^^^^^^^^^^^^^^^^^^^
+
+This function has to be modified to use the new datastructures and it is
+no longer recursive, instead recursion happens as part of unification.
+
+.. code:: ipython2
+
+ def compose(f, g):
+
+ (f_in, f_out), (g_in, g_out) = f, g
+
+ if not g_in:
+ fg_in, fg_out = f_in, stack_concat(g_out, f_out)
+
+ elif not f_out:
+ fg_in, fg_out = stack_concat(f_in, g_in), g_out
+
+ else: # Unify and update.
+
+ s = unify(g_in, f_out)
+
+ if s == False: # s can also be the empty dict, which is ok.
+ raise TypeError('Cannot unify %r and %r.' % (fo, gi))
+
+ fg_in, fg_out = update(s, (f_in, g_out))
+
+ return fg_in, fg_out
+
+
+ stack_concat = lambda q, e: (q[0], stack_concat(q[1], e)) if q else e
+
+I don't want to rewrite all the defs myself, so I'll write a little
+conversion function instead. This is programmer's laziness.
+
+.. code:: ipython2
+
+ def sequence_to_stack(seq, stack=StackJoyType(23)):
+ for item in seq: stack = item, stack
+ return stack
+
+ NEW_DEFS = {
+ name: (sequence_to_stack(i), sequence_to_stack(o))
+ for name, (i, o) in DEFS.iteritems()
+ }
+
+ globals().update(NEW_DEFS)
+
+.. code:: ipython2
+
+ stack = S[0], (S[0], S[0])
+
+.. code:: ipython2
+
+ C(stack, uncons)
+
+
+
+
+.. parsed-literal::
+
+ ((a0, s0), (s0, (a0, (a0, s0))))
+
+
+
+.. code:: ipython2
+
+ C(C(stack, uncons), uncons)
+
+
+
+
+.. parsed-literal::
+
+ ((a0, (a1, s0)), (s0, (a1, (a0, (a0, (a1, s0))))))
+
+
+
+The display function should be changed too.
+
+``doc_from_stack_effect()`` version 2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Clunky junk, but it will suffice for now.
+
+.. code:: ipython2
+
+ def doc_from_stack_effect(inputs, outputs):
+ switch = [False] # Do we need to display the '...' for the rest of the main stack?
+ i, o = _f(inputs, switch), _f(outputs, switch)
+ if switch[0]:
+ i.append('...')
+ o.append('...')
+ return '(%s--%s)' % (
+ ' '.join(reversed([''] + i)),
+ ' '.join(reversed(o + [''])),
+ )
+
+
+ def _f(term, switch):
+ a = []
+ while term and isinstance(term, tuple):
+ item, term = term
+ a.append(item)
+ assert isinstance(term, StackJoyType), repr(term)
+ a = [_to_str(i, term, switch) for i in a]
+ return a
+
+
+ def _to_str(term, stack, switch):
+ if not isinstance(term, tuple):
+ if term == stack:
+ switch[0] = True
+ return '[...]'
+ return (
+ '[.%i.]' % term.number
+ if isinstance(term, StackJoyType)
+ else str(term)
+ )
+
+ a = []
+ while term and isinstance(term, tuple):
+ item, term = term
+ a.append(_to_str(item, stack, switch))
+ assert isinstance(term, StackJoyType), repr(term)
+ if term == stack:
+ switch[0] = True
+ end = '...'
+ else:
+ end = '.%i.' % term.number
+ a.append(end)
+ return '[%s]' % ' '.join(a)
+
+.. code:: ipython2
+
+ for name, stack_effect_comment in sorted(NEW_DEFS.items()):
+ print name, '=', doc_from_stack_effect(*stack_effect_comment)
+
+
+.. parsed-literal::
+
+ ccons = (a0 a1 [.0.] -- [a0 a1 .0.])
+ cons = (a1 [.1.] -- [a1 .1.])
+ divmod_ = (n2 n1 -- n4 n3)
+ dup = (a1 -- a1 a1)
+ dupd = (a2 a1 -- a2 a2 a1)
+ first = ([a1 .1.] -- a1)
+ mul = (n1 n2 -- n3)
+ 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 --)
+ pred = (n1 -- n2)
+ rest = ([a1 .1.] -- [.1.])
+ roll_down = (a1 a2 a3 -- a2 a3 a1)
+ roll_up = (a1 a2 a3 -- a3 a1 a2)
+ rrest = ([a0 a1 .0.] -- [.0.])
+ second = ([a0 a1 .0.] -- a1)
+ sqrt = (n0 -- n1)
+ succ = (n1 -- n2)
+ swap = (a1 a2 -- a2 a1)
+ swons = ([.0.] a0 -- [a0 .0.])
+ third = ([a0 a1 a2 .0.] -- a2)
+ tuck = (a2 a1 -- a1 a2 a1)
+ uncons = ([a1 .1.] -- a1 [.1.])
+
+
+.. code:: ipython2
+
+ print ; print doc_from_stack_effect(*stack)
+ print ; print doc_from_stack_effect(*C(stack, uncons))
+ print ; print doc_from_stack_effect(*C(C(stack, uncons), uncons))
+ print ; print doc_from_stack_effect(*C(C(stack, uncons), cons))
+
+
+.. parsed-literal::
+
+
+ (... -- ... [...])
+
+ (... a0 -- ... a0 a0 [...])
+
+ (... a1 a0 -- ... a1 a0 a0 a1 [...])
+
+ (... a0 -- ... a0 [a0 ...])
+
+
+.. code:: ipython2
+
+ print doc_from_stack_effect(*C(ccons, stack))
+
+
+.. parsed-literal::
+
+ (... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])
+
+
+.. code:: ipython2
+
+ Q = C(ccons, stack)
+
+ Q
+
+
+
+
+.. parsed-literal::
+
+ ((s0, (a0, (a1, s1))), (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1)))
+
+
+
+``compile_()`` version 3
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+This makes the ``compile_()`` function pretty simple as the stack effect
+comments are now already in the form needed for the Python code:
+
+.. code:: ipython2
+
+ def compile_(name, f, doc=None):
+ i, o = f
+ if doc is None:
+ doc = doc_from_stack_effect(i, o)
+ return '''def %s(stack):
+ """%s"""
+ %s = stack
+ return %s''' % (name, doc, i, o)
+
+.. code:: ipython2
+
+ print compile_('Q', Q)
+
+
+.. parsed-literal::
+
+ def Q(stack):
+ """(... a1 a0 [.0.] -- ... [a1 a0 .0.] [[a1 a0 .0.] ...])"""
+ (s0, (a0, (a1, s1))) = stack
+ return (((a1, (a0, s0)), s1), ((a1, (a0, s0)), s1))
+
+
+.. code:: ipython2
+
+ unstack = (S[1], S[0]), S[1]
+ enstacken = S[0], (S[0], S[1])
+
+.. code:: ipython2
+
+ print doc_from_stack_effect(*unstack)
+
+
+.. parsed-literal::
+
+ ([.1.] --)
+
+
+.. code:: ipython2
+
+ print doc_from_stack_effect(*enstacken)
+
+
+.. parsed-literal::
+
+ (-- [.0.])
+
+
+.. code:: ipython2
+
+ print doc_from_stack_effect(*C(cons, unstack))
+
+
+.. parsed-literal::
+
+ (a0 [.0.] -- a0)
+
+
+.. code:: ipython2
+
+ print doc_from_stack_effect(*C(cons, enstacken))
+
+
+.. parsed-literal::
+
+ (a0 [.0.] -- [[a0 .0.] .1.])
+
+
+.. code:: ipython2
+
+ C(cons, unstack)
+
+
+
+
+.. parsed-literal::
+
+ ((s0, (a0, s1)), (a0, s0))
+
+
+
+Sets of Stack Effects
+---------------------
+
+...
+
+``concat``
+----------
+
+How to deal with ``concat``?
+
+::
+
+ concat ([.0.] [.1.] -- [.0. .1.])
+
+We would like to represent this in Python somehow...
+
+.. code:: ipython2
+
+ concat = (S[0], S[1]), ((S[0], S[1]),)
+
+But this is actually ``cons`` with the first argument restricted to be a
+stack:
+
+::
+
+ ([.0.] [.1.] -- [[.0.] .1.])
+
+What we have implemented so far would actually only permit:
+
+::
+
+ ([.0.] [.1.] -- [.2.])
+
+.. code:: ipython2
+
+ concat = (S[0], S[1]), (S[2],)
+
+Which works but can lose information. Consider ``cons concat``, this is
+how much information we *could* retain:
+
+::
+
+ (1 [.0.] [.1.] -- [1 .0. .1.])
+
+As opposed to just:
+
+::
+
+ (1 [.0.] [.1.] -- [.2.])
+
+Which works but can lose information. Consider ``cons concat``, this is
+how much information we *could* retain:
+
+::
+
+ (1 [.0.] [.1.] -- [1 .0. .1.]) uncons uncons
+
+ (1 [.0.] [.1.] -- 1 [.0. .1.]) uncons
+ So far so good...
+ (1 [2 .2.] [.1.] -- 1 2 [.2. .1.])
+
+
+
+
+ (1 [.0.] [.1.] -- 1 [.0. .1.]) ([a1 .10.] -- a1 [.10.])
+ w/ { [a1 .10.] : [ .0. .1.] }
+ -or-
+ w/ { [ .0. .1.] : [a1 .10. ] }
+
+Typing Combinators
+------------------
+
+TBD
+
+This is an open subject.
+
+The obvious thing is that you now need two pairs of tuples to describe
+the combinators' effects, a stack effect comment and an expression
+effect comment:
+
+::
+
+ dip (a [F] --)--(-- F a)
+
+One thing that might help is...
+
+Abstract Interpretation
+-----------------------
+
+Something else...
+-----------------
+
+::
+
+ [4 5 ...] 2 1 0 pop∘swap∘roll<∘rest∘rest∘cons∘cons
+ [4 5 ...] 2 1 swap∘roll<∘rest∘rest∘cons∘cons
+ [4 5 ...] 1 2 roll<∘rest∘rest∘cons∘cons
+ 1 2 [4 5 ...] rest∘rest∘cons∘cons
+ 1 2 [5 ...] rest∘cons∘cons
+ 1 2 [...] cons∘cons
+ 1 [2 ...] cons
+ [1 2 ...]
+
+Eh?
diff --git a/docs/sphinx_docs/notebooks/index.rst b/docs/sphinx_docs/notebooks/index.rst
index d36d883..dc390b9 100644
--- a/docs/sphinx_docs/notebooks/index.rst
+++ b/docs/sphinx_docs/notebooks/index.rst
@@ -9,13 +9,15 @@ These essays are adapted from Jupyter notebooks. I hope to have those hosted so
:maxdepth: 2
Developing
+ Quadratic
Replacing
+ Recursion_Combinators
Ordered_Binary_Trees
Treestep
Generator_Programs
Newton-Raphson
- Quadratic
Zipper
+ Types
NoUpdates
Categorical
diff --git a/joy/library.py b/joy/library.py
index f754093..c3e00c7 100644
--- a/joy/library.py
+++ b/joy/library.py
@@ -25,12 +25,15 @@ function.
'''
from inspect import getdoc
from functools import wraps
+from inspect import getmembers, isfunction
import operator, math
from .parser import text_to_expression, Symbol
from .utils.stack import list_to_stack, iter_stack, pick, concat
from .utils.brutal_hackery import rename_code_object
+from .utils import generated_library as genlib
+
_dictionary = {}
@@ -88,12 +91,8 @@ def add_aliases(D, A):
definitions = ('''\
-second == rest first
-third == rest rest first
of == swap at
product == 1 swap [*] step
-swons == swap cons
-swoncat == swap concat
flatten == [] swap [concat] step
unit == [] cons
quoted == [unit] dip
@@ -128,6 +127,10 @@ codireco == cons dip rest cons
make_generator == [codireco] ccons
ccons == cons cons
'''
+##second == rest first
+##third == rest rest first
+##swons == swap cons
+##swoncat == swap concat
##Zipper
##z-down == [] swap uncons swap
@@ -258,6 +261,11 @@ def _text_to_defs(text):
#
+# Load the auto-generated primitives into the dictionary.
+for name, primitive in getmembers(genlib, isfunction):
+ inscribe(SimpleFunctionWrapper(primitive))
+
+
@inscribe
@SimpleFunctionWrapper
def parse(stack):
@@ -267,30 +275,30 @@ def parse(stack):
return expression, stack
-@inscribe
-@SimpleFunctionWrapper
-def first(stack):
- '''
- ::
-
- first == uncons pop
-
- '''
- ((head, tail), stack) = stack
- return head, stack
+##@inscribe
+##@SimpleFunctionWrapper
+##def first(stack):
+## '''
+## ::
+##
+## first == uncons pop
+##
+## '''
+## ((head, tail), stack) = stack
+## return head, stack
-@inscribe
-@SimpleFunctionWrapper
-def rest(stack):
- '''
- ::
-
- rest == uncons popd
-
- '''
- ((head, tail), stack) = stack
- return tail, stack
+##@inscribe
+##@SimpleFunctionWrapper
+##def rest(stack):
+## '''
+## ::
+##
+## rest == uncons popd
+##
+## '''
+## ((head, tail), stack) = stack
+## return tail, stack
@inscribe
@@ -479,28 +487,28 @@ def sort_(S):
return list_to_stack(sorted(iter_stack(tos))), stack
-@inscribe
-@SimpleFunctionWrapper
-def cons(S):
- '''
- The cons operator expects a list on top of the stack and the potential
- member below. The effect is to add the potential member into the
- aggregate.
- '''
- (tos, (second, stack)) = S
- return (second, tos), stack
+##@inscribe
+##@SimpleFunctionWrapper
+##def cons(S):
+## '''
+## The cons operator expects a list on top of the stack and the potential
+## member below. The effect is to add the potential member into the
+## aggregate.
+## '''
+## (tos, (second, stack)) = S
+## return (second, tos), stack
-@inscribe
-@SimpleFunctionWrapper
-def uncons(S):
- '''
- Inverse of cons, removes an item from the top of the list on the stack
- and places it under the remaining list.
- '''
- (tos, stack) = S
- item, tos = tos
- return tos, (item, stack)
+##@inscribe
+##@SimpleFunctionWrapper
+##def uncons(S):
+## '''
+## Inverse of cons, removes an item from the top of the list on the stack
+## and places it under the remaining list.
+## '''
+## (tos, stack) = S
+## item, tos = tos
+## return tos, (item, stack)
@inscribe
@@ -516,52 +524,52 @@ def clear(stack):
return ()
-@inscribe
-@SimpleFunctionWrapper
-def dup(S):
- '''Duplicate the top item on the stack.'''
- (tos, stack) = S
- return tos, (tos, stack)
+##@inscribe
+##@SimpleFunctionWrapper
+##def dup(S):
+## '''Duplicate the top item on the stack.'''
+## (tos, stack) = S
+## return tos, (tos, stack)
-@inscribe
-@SimpleFunctionWrapper
-def over(S):
- '''
- Copy the second item down on the stack to the top of the stack.
- ::
-
- a b over
- --------------
- a b a
-
- '''
- second = S[1][0]
- return second, S
+##@inscribe
+##@SimpleFunctionWrapper
+##def over(S):
+## '''
+## Copy the second item down on the stack to the top of the stack.
+## ::
+##
+## a b over
+## --------------
+## a b a
+##
+## '''
+## second = S[1][0]
+## return second, S
-@inscribe
-@SimpleFunctionWrapper
-def tuck(S):
- '''
- Copy the item at TOS under the second item of the stack.
- ::
-
- a b tuck
- --------------
- b a b
-
- '''
- (tos, (second, stack)) = S
- return tos, (second, (tos, stack))
+##@inscribe
+##@SimpleFunctionWrapper
+##def tuck(S):
+## '''
+## Copy the item at TOS under the second item of the stack.
+## ::
+##
+## a b tuck
+## --------------
+## b a b
+##
+## '''
+## (tos, (second, stack)) = S
+## return tos, (second, (tos, stack))
-@inscribe
-@SimpleFunctionWrapper
-def swap(S):
- '''Swap the top two items on stack.'''
- (tos, (second, stack)) = S
- return second, (tos, stack)
+##@inscribe
+##@SimpleFunctionWrapper
+##def swap(S):
+## '''Swap the top two items on stack.'''
+## (tos, (second, stack)) = S
+## return second, (tos, stack)
@inscribe
@@ -572,14 +580,14 @@ def swaack(stack):
return stack, old_stack
-@inscribe
-@SimpleFunctionWrapper
-def stack_(stack):
- '''
- The stack operator pushes onto the stack a list containing all the
- elements of the stack.
- '''
- return stack, stack
+##@inscribe
+##@SimpleFunctionWrapper
+##def stack_(stack):
+## '''
+## The stack operator pushes onto the stack a list containing all the
+## elements of the stack.
+## '''
+## return stack, stack
@inscribe
@@ -592,42 +600,42 @@ def unstack(stack):
return stack[0]
-@inscribe
-@SimpleFunctionWrapper
-def pop(stack):
- '''Pop and discard the top item from the stack.'''
- return stack[1]
+##@inscribe
+##@SimpleFunctionWrapper
+##def pop(stack):
+## '''Pop and discard the top item from the stack.'''
+## return stack[1]
-@inscribe
-@SimpleFunctionWrapper
-def popd(stack):
- '''Pop and discard the second item from the stack.'''
- (tos, (_, stack)) = stack
- return tos, stack
+##@inscribe
+##@SimpleFunctionWrapper
+##def popd(stack):
+## '''Pop and discard the second item from the stack.'''
+## (tos, (_, stack)) = stack
+## return tos, stack
-@inscribe
-@SimpleFunctionWrapper
-def popdd(stack):
- '''Pop and discard the third item from the stack.'''
- (tos, (second, (_, stack))) = stack
- return tos, (second, stack)
+##@inscribe
+##@SimpleFunctionWrapper
+##def popdd(stack):
+## '''Pop and discard the third item from the stack.'''
+## (tos, (second, (_, stack))) = stack
+## return tos, (second, stack)
-@inscribe
-@SimpleFunctionWrapper
-def popop(stack):
- '''Pop and discard the first and second items from the stack.'''
- return stack[1][1]
+##@inscribe
+##@SimpleFunctionWrapper
+##def popop(stack):
+## '''Pop and discard the first and second items from the stack.'''
+## return stack[1][1]
-@inscribe
-@SimpleFunctionWrapper
-def dupd(S):
- '''Duplicate the second item on the stack.'''
- (tos, (second, stack)) = S
- return tos, (second, (second, stack))
+##@inscribe
+##@SimpleFunctionWrapper
+##def dupd(S):
+## '''Duplicate the second item on the stack.'''
+## (tos, (second, stack)) = S
+## return tos, (second, (second, stack))
@inscribe
@@ -760,34 +768,34 @@ def sqrt(a):
return r
-@inscribe
-@SimpleFunctionWrapper
-def rollup(S):
- '''
- ::
-
- a b c
- -----------
- b c a
-
- '''
- (a, (b, (c, stack))) = S
- return b, (c, (a, stack))
+##@inscribe
+##@SimpleFunctionWrapper
+##def rollup(S):
+## '''
+## ::
+##
+## a b c
+## -----------
+## b c a
+##
+## '''
+## (a, (b, (c, stack))) = S
+## return b, (c, (a, stack))
-@inscribe
-@SimpleFunctionWrapper
-def rolldown(S):
- '''
- ::
-
- a b c
- -----------
- c a b
-
- '''
- (a, (b, (c, stack))) = S
- return c, (a, (b, stack))
+##@inscribe
+##@SimpleFunctionWrapper
+##def rolldown(S):
+## '''
+## ::
+##
+## a b c
+## -----------
+## c a b
+##
+## '''
+## (a, (b, (c, stack))) = S
+## return c, (a, (b, stack))
#def execute(S):