From 22f7c6da00a1da5765453802f74486ad7de76992 Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Wed, 6 Jun 2018 07:59:06 -0700 Subject: [PATCH] Minor docs edits. --- docs/Ordered_Binary_Trees.html | 183 ++++++++++---------------------- docs/Ordered_Binary_Trees.ipynb | 172 ++++++++---------------------- docs/Ordered_Binary_Trees.md | 94 ++-------------- docs/Ordered_Binary_Trees.rst | 103 +++--------------- 4 files changed, 126 insertions(+), 426 deletions(-) diff --git a/docs/Ordered_Binary_Trees.html b/docs/Ordered_Binary_Trees.html index 221b317..e5a218f 100644 --- a/docs/Ordered_Binary_Trees.html +++ b/docs/Ordered_Binary_Trees.html @@ -11775,7 +11775,7 @@ div#notebook {
-

Treating Trees I

Although any expression in Joy can be considered to describe a tree with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about ordered binary trees and how to make and use them.

+

Treating Trees I: Ordered Binary Trees

Although any expression in Joy can be considered to describe a tree with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about ordered binary trees and how to make and use them.

The basic structure, in a crude type notation, is:

Tree :: [] | [key value Tree Tree]
@@ -11886,6 +11886,24 @@ key      [value [] []]      cons
 
+
+
+ + +
+ +
+ + +
+
['k' 'v' [] []]
+
+
+
+ +
+
+
@@ -12498,7 +12516,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
-

Interlude: cmp combinator

Instead of mucking about with nested ifte combinators let's just go whole hog and define cmp which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:

+

Interlude: cmp combinator

Instead of mucking about with nested ifte combinators let's use cmp which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:

   a b [G] [E] [L] cmp
 ------------------------- a > b
@@ -12518,47 +12536,6 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
In [20]:
-
-
-
from joy.library import FunctionWrapper
-from joy.utils.stack import pushback
-from notebook_preamble import D
-
-
-@FunctionWrapper
-def cmp_(stack, expression, dictionary):
-    '''
-    cmp takes two values and three quoted programs on the stack and runs
-    one of the three depending on the results of comparing the two values:
-
-           a b [G] [E] [L] cmp
-        ------------------------- a > b
-                G
-
-           a b [G] [E] [L] cmp
-        ------------------------- a = b
-                    E
-
-           a b [G] [E] [L] cmp
-        ------------------------- a < b
-                        L
-    '''
-    L, (E, (G, (b, (a, stack)))) = stack
-    expression = pushback(G if a > b else L if a < b else E, expression)
-    return stack, expression, dictionary
-
-
-D['cmp'] = cmp_
-
- -
-
-
- -
-
-
-
In [21]:
J("1 0 ['G'] ['E'] ['L'] cmp")
@@ -12589,7 +12566,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
-
In [22]:
+
In [21]:
J("1 1 ['G'] ['E'] ['L'] cmp")
@@ -12620,7 +12597,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
-
In [23]:
+
In [22]:
J("0 1 ['G'] ['E'] ['L'] cmp")
@@ -12706,7 +12683,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
-
In [24]:
+
In [23]:
define('P == over [popop popop first] nullary')
@@ -12755,7 +12732,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
-
In [25]:
+
In [24]:
define('Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec')
@@ -12768,7 +12745,7 @@ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
-
In [26]:
+
In [25]:
J('[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add')  # Still works.
@@ -12938,7 +12915,7 @@ key left-keys right-keys
 
-
In [27]:
+
In [26]:
define('Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec')
@@ -12959,7 +12936,7 @@ key left-keys right-keys
 
-
In [28]:
+
In [27]:
J('[] [foo] Tree-iter')  #  It doesn't matter what F is as it won't be used.
@@ -12990,7 +12967,7 @@ key left-keys right-keys
 
-
In [29]:
+
In [28]:
J("['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter")
@@ -13021,7 +12998,7 @@ key left-keys right-keys
 
-
In [30]:
+
In [29]:
J("['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter")
@@ -13061,7 +13038,7 @@ key left-keys right-keys
 
-
In [31]:
+
In [30]:
J('[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step')
@@ -13092,7 +13069,7 @@ key left-keys right-keys
 
-
In [32]:
+
In [31]:
define('to_set == [] swap [0 swap Tree-add] step')
@@ -13105,7 +13082,7 @@ key left-keys right-keys
 
-
In [33]:
+
In [32]:
J('[3 9 5 2 8 6 7 8 4] to_set')
@@ -13145,7 +13122,7 @@ key left-keys right-keys
 
-
In [34]:
+
In [33]:
define('unique == [to_set [first] Tree-iter] cons run')
@@ -13158,7 +13135,7 @@ key left-keys right-keys
 
-
In [35]:
+
In [34]:
J('[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique')  # Filter duplicate items.
@@ -13302,7 +13279,7 @@ Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] g
 
-
In [36]:
+
In [35]:
#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')
@@ -13328,7 +13305,7 @@ Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] g
 
-
In [37]:
+
In [36]:
J('[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order')
@@ -13361,7 +13338,7 @@ Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] g
 
-

Parameterizing the [F] function is left as an exercise for the reader (for now.)

+

Parameterizing the [F] function is left as an exercise for the reader.

@@ -13528,7 +13505,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
-
In [38]:
+
In [37]:
# I don't want to deal with name conflicts with the above so I'm inlining everything here.
@@ -13555,7 +13532,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
-
In [39]:
+
In [38]:
J('["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get')
@@ -13586,7 +13563,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
-
In [40]:
+
In [39]:
J('["gary" 23 [] []] "gary" [popop "err"] Tree-get')
@@ -13617,7 +13594,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
-
In [41]:
+
In [40]:
J('''
@@ -13654,7 +13631,7 @@ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
-
In [52]:
+
In [41]:
J('''
@@ -13847,59 +13824,6 @@ T< == [dipdd] cons infra
-
-
-
-
In [42]:
-
-
-
from joy.library import FunctionWrapper, S_ifte
-
-
-@FunctionWrapper
-def cond(stack, expression, dictionary):
-  '''
-  like a case statement; works by rewriting into a chain of ifte.
-
-  [..[[Bi] Ti]..[D]] -> ...
-
-
-        [[[B0] T0] [[B1] T1] [D]] cond
-  -----------------------------------------
-     [B0] [T0] [[B1] [T1] [D] ifte] ifte
-
-  '''
-  conditions, stack = stack
-  if conditions:
-    expression = _cond(conditions, expression)
-    try:
-      # Attempt to preload the args to first ifte.
-      (P, (T, (E, expression))) = expression
-    except ValueError:
-      # If, for any reason, the argument to cond should happen to contain
-      # only the default clause then this optimization will fail.
-      pass
-    else:
-      stack = (E, (T, (P, stack)))
-  return stack, expression, dictionary
-
-
-def _cond(conditions, expression):
-  (clause, rest) = conditions
-  if not rest:  # clause is [D]
-    return clause
-  P, T = clause
-  return (P, (T, (_cond(rest, ()), (S_ifte, expression))))
-
-
-
-D['cond'] = cond
-
- -
-
-
-
@@ -14198,7 +14122,7 @@ E == [
-

Minor rearrangement:

+

Minor rearrangement, move dup into W:

W == dup [fourth] [fourth] while uncons uncons pop over
 E′ == roll> popop rest [W] dip cons dipd swap
@@ -14218,9 +14142,9 @@ E == [
 

Refactoring

W.rightmost == [fourth] [fourth] while
 W.unpack == uncons uncons pop
+W == dup W.rightmost W.unpack over
 E.clear_stuff == roll> popop rest
 E.delete == cons dipd
-W == dup W.rightmost W.unpack over
 E.0 == E.clear_stuff [W] dip E.delete swap
 E == [
     [[pop third not] pop fourth]
@@ -14241,7 +14165,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
 
-
In [43]:
+
In [42]:
DefinitionWrapper.add_definitions('''
@@ -14258,7 +14182,8 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
 T< == [dipdd] cons infra
 R0 == over first swap dup
 R1 == cons roll> [T>] [E] [T<] cmp
-Tree-Delete == [pop not] [pop] [R0] [R1] genrec''', D)
+Tree-Delete == [pop not] [pop] [R0] [R1] genrec
+''', D)
 
@@ -14268,7 +14193,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
-
In [44]:
+
In [43]:
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete ")
@@ -14299,7 +14224,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
 
-
In [45]:
+
In [44]:
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete ")
@@ -14330,7 +14255,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
 
-
In [46]:
+
In [45]:
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete ")
@@ -14361,7 +14286,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
 
-
In [47]:
+
In [46]:
J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete ")
@@ -14392,7 +14317,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
 
-
In [48]:
+
In [47]:
J('[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step')
@@ -14423,7 +14348,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
 
-
In [49]:
+
In [48]:
J("[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete ")
@@ -14454,7 +14379,7 @@ BTree-Delete == [pop not] swap [R0] [R1] genrec
 
-
In [50]:
+
In [49]:
J("[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete ")
diff --git a/docs/Ordered_Binary_Trees.ipynb b/docs/Ordered_Binary_Trees.ipynb
index f426b94..c9dfffe 100644
--- a/docs/Ordered_Binary_Trees.ipynb
+++ b/docs/Ordered_Binary_Trees.ipynb
@@ -4,7 +4,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "# Treating Trees I\n",
+    "# Treating Trees I: Ordered Binary Trees\n",
     "\n",
     "Although any expression in Joy can be considered to describe a [tree](https://en.wikipedia.org/wiki/Tree_structure) with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about [ordered binary trees](https://en.wikipedia.org/wiki/Binary_search_tree) and how to make and use them.\n",
     "\n",
@@ -92,7 +92,15 @@
    "cell_type": "code",
    "execution_count": 3,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "['k' 'v' [] []]\n"
+     ]
+    }
+   ],
    "source": [
     "J('\"v\" \"k\" Tree-new')"
    ]
@@ -521,7 +529,7 @@
    "metadata": {},
    "source": [
     "## Interlude: `cmp` combinator\n",
-    "Instead of mucking about with nested `ifte` combinators let's just go whole hog and define `cmp` which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:\n",
+    "Instead of mucking about with nested `ifte` combinators let's use `cmp` which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:\n",
     "\n",
     "       a b [G] [E] [L] cmp\n",
     "    ------------------------- a > b\n",
@@ -540,43 +548,6 @@
    "cell_type": "code",
    "execution_count": 20,
    "metadata": {},
-   "outputs": [],
-   "source": [
-    "from joy.library import FunctionWrapper\n",
-    "from joy.utils.stack import pushback\n",
-    "from notebook_preamble import D\n",
-    "\n",
-    "\n",
-    "@FunctionWrapper\n",
-    "def cmp_(stack, expression, dictionary):\n",
-    "    '''\n",
-    "    cmp takes two values and three quoted programs on the stack and runs\n",
-    "    one of the three depending on the results of comparing the two values:\n",
-    "\n",
-    "           a b [G] [E] [L] cmp\n",
-    "        ------------------------- a > b\n",
-    "                G\n",
-    "\n",
-    "           a b [G] [E] [L] cmp\n",
-    "        ------------------------- a = b\n",
-    "                    E\n",
-    "\n",
-    "           a b [G] [E] [L] cmp\n",
-    "        ------------------------- a < b\n",
-    "                        L\n",
-    "    '''\n",
-    "    L, (E, (G, (b, (a, stack)))) = stack\n",
-    "    expression = pushback(G if a > b else L if a < b else E, expression)\n",
-    "    return stack, expression, dictionary\n",
-    "\n",
-    "\n",
-    "D['cmp'] = cmp_"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 21,
-   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -592,7 +563,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 21,
    "metadata": {},
    "outputs": [
     {
@@ -609,7 +580,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 22,
    "metadata": {},
    "outputs": [
     {
@@ -674,7 +645,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 23,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -713,7 +684,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 24,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -722,7 +693,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 26,
+   "execution_count": 25,
    "metadata": {
     "scrolled": false
    },
@@ -865,7 +836,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 27,
+   "execution_count": 26,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -881,7 +852,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 27,
    "metadata": {},
    "outputs": [
     {
@@ -898,7 +869,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 28,
    "metadata": {},
    "outputs": [
     {
@@ -915,7 +886,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": 29,
    "metadata": {},
    "outputs": [
     {
@@ -940,7 +911,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": 30,
    "metadata": {},
    "outputs": [
     {
@@ -957,7 +928,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 31,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -966,7 +937,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
+   "execution_count": 32,
    "metadata": {},
    "outputs": [
     {
@@ -990,7 +961,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
+   "execution_count": 33,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -999,7 +970,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 35,
+   "execution_count": 34,
    "metadata": {
     "scrolled": true
    },
@@ -1117,7 +1088,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 36,
+   "execution_count": 35,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1141,7 +1112,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 37,
+   "execution_count": 36,
    "metadata": {},
    "outputs": [
     {
@@ -1160,7 +1131,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Parameterizing the `[F]` function is left as an exercise for the reader (for now.)"
+    "Parameterizing the `[F]` function is left as an exercise for the reader."
    ]
   },
   {
@@ -1310,7 +1281,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 38,
+   "execution_count": 37,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1333,7 +1304,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 39,
+   "execution_count": 38,
    "metadata": {},
    "outputs": [
     {
@@ -1350,7 +1321,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 40,
+   "execution_count": 39,
    "metadata": {},
    "outputs": [
     {
@@ -1367,7 +1338,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 41,
+   "execution_count": 40,
    "metadata": {},
    "outputs": [
     {
@@ -1390,7 +1361,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 52,
+   "execution_count": 41,
    "metadata": {},
    "outputs": [
     {
@@ -1552,55 +1523,6 @@
     "We have to handle three cases, so let's use `cond`."
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": 42,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from joy.library import FunctionWrapper, S_ifte\n",
-    "\n",
-    "\n",
-    "@FunctionWrapper\n",
-    "def cond(stack, expression, dictionary):\n",
-    "  '''\n",
-    "  like a case statement; works by rewriting into a chain of ifte.\n",
-    "\n",
-    "  [..[[Bi] Ti]..[D]] -> ...\n",
-    "\n",
-    "\n",
-    "        [[[B0] T0] [[B1] T1] [D]] cond\n",
-    "  -----------------------------------------\n",
-    "     [B0] [T0] [[B1] [T1] [D] ifte] ifte\n",
-    "\n",
-    "  '''\n",
-    "  conditions, stack = stack\n",
-    "  if conditions:\n",
-    "    expression = _cond(conditions, expression)\n",
-    "    try:\n",
-    "      # Attempt to preload the args to first ifte.\n",
-    "      (P, (T, (E, expression))) = expression\n",
-    "    except ValueError:\n",
-    "      # If, for any reason, the argument to cond should happen to contain\n",
-    "      # only the default clause then this optimization will fail.\n",
-    "      pass\n",
-    "    else:\n",
-    "      stack = (E, (T, (P, stack)))\n",
-    "  return stack, expression, dictionary\n",
-    "\n",
-    "\n",
-    "def _cond(conditions, expression):\n",
-    "  (clause, rest) = conditions\n",
-    "  if not rest:  # clause is [D]\n",
-    "    return clause\n",
-    "  P, T = clause\n",
-    "  return (P, (T, (_cond(rest, ()), (S_ifte, expression))))\n",
-    "\n",
-    "\n",
-    "\n",
-    "D['cond'] = cond"
-   ]
-  },
   {
    "cell_type": "markdown",
    "metadata": {},
@@ -1860,7 +1782,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "Minor rearrangement:\n",
+    "Minor rearrangement, move `dup` into `W`:\n",
     "\n",
     "    W == dup [fourth] [fourth] while uncons uncons pop over\n",
     "    E′ == roll> popop rest [W] dip cons dipd swap\n",
@@ -1879,9 +1801,9 @@
     "\n",
     "    W.rightmost == [fourth] [fourth] while\n",
     "    W.unpack == uncons uncons pop\n",
+    "    W == dup W.rightmost W.unpack over\n",
     "    E.clear_stuff == roll> popop rest\n",
     "    E.delete == cons dipd\n",
-    "    W == dup W.rightmost W.unpack over\n",
     "    E.0 == E.clear_stuff [W] dip E.delete swap\n",
     "    E == [\n",
     "        [[pop third not] pop fourth]\n",
@@ -1899,7 +1821,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 43,
+   "execution_count": 42,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -1917,12 +1839,13 @@
     "T< == [dipdd] cons infra\n",
     "R0 == over first swap dup\n",
     "R1 == cons roll> [T>] [E] [T<] cmp\n",
-    "Tree-Delete == [pop not] [pop] [R0] [R1] genrec''', D)"
+    "Tree-Delete == [pop not] [pop] [R0] [R1] genrec\n",
+    "''', D)"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 44,
+   "execution_count": 43,
    "metadata": {},
    "outputs": [
     {
@@ -1939,7 +1862,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 45,
+   "execution_count": 44,
    "metadata": {},
    "outputs": [
     {
@@ -1956,7 +1879,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 46,
+   "execution_count": 45,
    "metadata": {},
    "outputs": [
     {
@@ -1973,7 +1896,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 47,
+   "execution_count": 46,
    "metadata": {},
    "outputs": [
     {
@@ -1990,7 +1913,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 48,
+   "execution_count": 47,
    "metadata": {},
    "outputs": [
     {
@@ -2007,7 +1930,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 49,
+   "execution_count": 48,
    "metadata": {},
    "outputs": [
     {
@@ -2024,7 +1947,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 50,
+   "execution_count": 49,
    "metadata": {
     "scrolled": true
    },
@@ -2099,11 +2022,6 @@
     "    Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec\n",
     "\n"
    ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": []
   }
  ],
  "metadata": {
diff --git a/docs/Ordered_Binary_Trees.md b/docs/Ordered_Binary_Trees.md
index 368c76e..adecfb7 100644
--- a/docs/Ordered_Binary_Trees.md
+++ b/docs/Ordered_Binary_Trees.md
@@ -1,5 +1,5 @@
 
-# Treating Trees I
+# Treating Trees I: Ordered Binary Trees
 
 Although any expression in Joy can be considered to describe a [tree](https://en.wikipedia.org/wiki/Tree_structure) with the quotes as compound nodes and the non-quote values as leaf nodes, in this page I want to talk about [ordered binary trees](https://en.wikipedia.org/wiki/Binary_search_tree) and how to make and use them.
 
@@ -64,6 +64,9 @@ define('Tree-new == swap [[] []] cons cons')
 J('"v" "k" Tree-new')
 ```
 
+    ['k' 'v' [] []]
+
+
 (As an implementation detail, the `[[] []]` literal used in the definition of `Tree-new` will be reused to supply the *constant* tail for *all* new nodes produced by it.  This is one of those cases where you get amortized storage "for free" by using [persistent datastructures](https://en.wikipedia.org/wiki/Persistent_data_structure).  Because the tail, which is `((), ((), ()))` in Python, is immutable and embedded in the definition body for `Tree-new`, all new nodes can reuse it as their own tail without fear that some other code somewhere will change it.)
 
 ### Adding to a non-empty node.
@@ -302,7 +305,7 @@ J('[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step')
 
 
 ## Interlude: `cmp` combinator
-Instead of mucking about with nested `ifte` combinators let's just go whole hog and define `cmp` which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:
+Instead of mucking about with nested `ifte` combinators let's use `cmp` which takes two values and three quoted programs on the stack and runs one of the three depending on the results of comparing the two values:
 
        a b [G] [E] [L] cmp
     ------------------------- a > b
@@ -317,39 +320,6 @@ Instead of mucking about with nested `ifte` combinators let's just go whole hog
                     L
 
 
-```python
-from joy.library import FunctionWrapper
-from joy.utils.stack import pushback
-from notebook_preamble import D
-
-
-@FunctionWrapper
-def cmp_(stack, expression, dictionary):
-    '''
-    cmp takes two values and three quoted programs on the stack and runs
-    one of the three depending on the results of comparing the two values:
-
-           a b [G] [E] [L] cmp
-        ------------------------- a > b
-                G
-
-           a b [G] [E] [L] cmp
-        ------------------------- a = b
-                    E
-
-           a b [G] [E] [L] cmp
-        ------------------------- a < b
-                        L
-    '''
-    L, (E, (G, (b, (a, stack)))) = stack
-    expression = pushback(G if a > b else L if a < b else E, expression)
-    return stack, expression, dictionary
-
-
-D['cmp'] = cmp_
-```
-
-
 ```python
 J("1 0 ['G'] ['E'] ['L'] cmp")
 ```
@@ -681,7 +651,7 @@ J('[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order')
     2 3 4 5 6 7 8 9
 
 
-Parameterizing the `[F]` function is left as an exercise for the reader (for now.)
+Parameterizing the `[F]` function is left as an exercise for the reader.
 
 ## Getting values by key
 Let's derive a function that accepts a tree and a key and returns the value associated with that key.
@@ -937,51 +907,6 @@ We have found the node in the tree where `key` equals `node_key`.  We need to re
 
 We have to handle three cases, so let's use `cond`.
 
-
-```python
-from joy.library import FunctionWrapper, S_ifte
-
-
-@FunctionWrapper
-def cond(stack, expression, dictionary):
-  '''
-  like a case statement; works by rewriting into a chain of ifte.
-
-  [..[[Bi] Ti]..[D]] -> ...
-
-
-        [[[B0] T0] [[B1] T1] [D]] cond
-  -----------------------------------------
-     [B0] [T0] [[B1] [T1] [D] ifte] ifte
-
-  '''
-  conditions, stack = stack
-  if conditions:
-    expression = _cond(conditions, expression)
-    try:
-      # Attempt to preload the args to first ifte.
-      (P, (T, (E, expression))) = expression
-    except ValueError:
-      # If, for any reason, the argument to cond should happen to contain
-      # only the default clause then this optimization will fail.
-      pass
-    else:
-      stack = (E, (T, (P, stack)))
-  return stack, expression, dictionary
-
-
-def _cond(conditions, expression):
-  (clause, rest) = conditions
-  if not rest:  # clause is [D]
-    return clause
-  P, T = clause
-  return (P, (T, (_cond(rest, ()), (S_ifte, expression))))
-
-
-
-D['cond'] = cond
-```
-
 #### One or more child nodes are `[]`
 The first two cases are symmetrical: if we only have one non-empty child node return it.  If both child nodes are empty return an empty node.
 
@@ -1127,7 +1052,7 @@ Substituting:
         [[E′] cons infra]
     ] cond
 
-Minor rearrangement:
+Minor rearrangement, move `dup` into `W`:
 
     W == dup [fourth] [fourth] while uncons uncons pop over
     E′ == roll> popop rest [W] dip cons dipd swap
@@ -1141,9 +1066,9 @@ Minor rearrangement:
 
     W.rightmost == [fourth] [fourth] while
     W.unpack == uncons uncons pop
+    W == dup W.rightmost W.unpack over
     E.clear_stuff == roll> popop rest
     E.delete == cons dipd
-    W == dup W.rightmost W.unpack over
     E.0 == E.clear_stuff [W] dip E.delete swap
     E == [
         [[pop third not] pop fourth]
@@ -1174,7 +1099,8 @@ T> == [dipd] cons infra
 T< == [dipdd] cons infra
 R0 == over first swap dup
 R1 == cons roll> [T>] [E] [T<] cmp
-Tree-Delete == [pop not] [pop] [R0] [R1] genrec''', D)
+Tree-Delete == [pop not] [pop] [R0] [R1] genrec
+''', D)
 ```
 
 
diff --git a/docs/Ordered_Binary_Trees.rst b/docs/Ordered_Binary_Trees.rst
index 883d431..612fd66 100644
--- a/docs/Ordered_Binary_Trees.rst
+++ b/docs/Ordered_Binary_Trees.rst
@@ -1,6 +1,6 @@
 
-Treating Trees I
-================
+Treating Trees I: Ordered Binary Trees
+======================================
 
 Although any expression in Joy can be considered to describe a
 `tree `__ with the quotes
@@ -96,6 +96,12 @@ Definition:
 
     J('"v" "k" Tree-new')
 
+
+.. parsed-literal::
+
+    ['k' 'v' [] []]
+
+
 (As an implementation detail, the ``[[] []]`` literal used in the
 definition of ``Tree-new`` will be reused to supply the *constant* tail
 for *all* new nodes produced by it. This is one of those cases where you
@@ -420,10 +426,10 @@ Examples
 Interlude: ``cmp`` combinator
 -----------------------------
 
-Instead of mucking about with nested ``ifte`` combinators let's just go
-whole hog and define ``cmp`` which takes two values and three quoted
-programs on the stack and runs one of the three depending on the results
-of comparing the two values:
+Instead of mucking about with nested ``ifte`` combinators let's use
+``cmp`` which takes two values and three quoted programs on the stack
+and runs one of the three depending on the results of comparing the two
+values:
 
 ::
 
@@ -439,38 +445,6 @@ of comparing the two values:
     ------------------------- a < b
                     L
 
-.. code:: ipython2
-
-    from joy.library import FunctionWrapper
-    from joy.utils.stack import pushback
-    from notebook_preamble import D
-    
-    
-    @FunctionWrapper
-    def cmp_(stack, expression, dictionary):
-        '''
-        cmp takes two values and three quoted programs on the stack and runs
-        one of the three depending on the results of comparing the two values:
-    
-               a b [G] [E] [L] cmp
-            ------------------------- a > b
-                    G
-    
-               a b [G] [E] [L] cmp
-            ------------------------- a = b
-                        E
-    
-               a b [G] [E] [L] cmp
-            ------------------------- a < b
-                            L
-        '''
-        L, (E, (G, (b, (a, stack)))) = stack
-        expression = pushback(G if a > b else L if a < b else E, expression)
-        return stack, expression, dictionary
-    
-    
-    D['cmp'] = cmp_
-
 .. code:: ipython2
 
     J("1 0 ['G'] ['E'] ['L'] cmp")
@@ -930,7 +904,7 @@ Now we can sort sequences.
 
 
 Parameterizing the ``[F]`` function is left as an exercise for the
-reader (for now.)
+reader.
 
 Getting values by key
 ---------------------
@@ -1291,50 +1265,6 @@ need to replace the current node with something
 
 We have to handle three cases, so let's use ``cond``.
 
-.. code:: ipython2
-
-    from joy.library import FunctionWrapper, S_ifte
-    
-    
-    @FunctionWrapper
-    def cond(stack, expression, dictionary):
-      '''
-      like a case statement; works by rewriting into a chain of ifte.
-    
-      [..[[Bi] Ti]..[D]] -> ...
-    
-    
-            [[[B0] T0] [[B1] T1] [D]] cond
-      -----------------------------------------
-         [B0] [T0] [[B1] [T1] [D] ifte] ifte
-    
-      '''
-      conditions, stack = stack
-      if conditions:
-        expression = _cond(conditions, expression)
-        try:
-          # Attempt to preload the args to first ifte.
-          (P, (T, (E, expression))) = expression
-        except ValueError:
-          # If, for any reason, the argument to cond should happen to contain
-          # only the default clause then this optimization will fail.
-          pass
-        else:
-          stack = (E, (T, (P, stack)))
-      return stack, expression, dictionary
-    
-    
-    def _cond(conditions, expression):
-      (clause, rest) = conditions
-      if not rest:  # clause is [D]
-        return clause
-      P, T = clause
-      return (P, (T, (_cond(rest, ()), (S_ifte, expression))))
-    
-    
-    
-    D['cond'] = cond
-
 One or more child nodes are ``[]``
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1534,7 +1464,7 @@ Substituting:
         [[E′] cons infra]
     ] cond
 
-Minor rearrangement:
+Minor rearrangement, move ``dup`` into ``W``:
 
 ::
 
@@ -1553,9 +1483,9 @@ Refactoring
 
     W.rightmost == [fourth] [fourth] while
     W.unpack == uncons uncons pop
+    W == dup W.rightmost W.unpack over
     E.clear_stuff == roll> popop rest
     E.delete == cons dipd
-    W == dup W.rightmost W.unpack over
     E.0 == E.clear_stuff [W] dip E.delete swap
     E == [
         [[pop third not] pop fourth]
@@ -1587,7 +1517,8 @@ program.
     T< == [dipdd] cons infra
     R0 == over first swap dup
     R1 == cons roll> [T>] [E] [T<] cmp
-    Tree-Delete == [pop not] [pop] [R0] [R1] genrec''', D)
+    Tree-Delete == [pop not] [pop] [R0] [R1] genrec
+    ''', D)
 
 .. code:: ipython2