OSDN Git Service

ReST docs & library edits for Sphinx
authorSimon Forman <sforman@hushmail.com>
Wed, 25 Apr 2018 05:07:21 +0000 (22:07 -0700)
committerSimon Forman <sforman@hushmail.com>
Wed, 25 Apr 2018 05:07:21 +0000 (22:07 -0700)
Used Pandoc to convert the notebooks to rst format.  Used 2to3 to edit
the function signatures that were causing sphinx to error out.  Am I
really the only one who uses that syntax?

19 files changed:
docs/0. This Implementation of Joy in Python.rst [new file with mode: 0644]
docs/1. Basic Use of Joy in a Notebook.rst [new file with mode: 0644]
docs/2. Library Examples.rst [new file with mode: 0644]
docs/3. Developing a Program.rst [new file with mode: 0644]
docs/4. Replacing Functions in the Dictionary.rst [new file with mode: 0644]
docs/Advent of Code 2017 December 1st.rst [new file with mode: 0644]
docs/Advent of Code 2017 December 2nd.rst [new file with mode: 0644]
docs/Advent of Code 2017 December 3rd.rst [new file with mode: 0644]
docs/Advent of Code 2017 December 4th.rst [new file with mode: 0644]
docs/Advent of Code 2017 December 5th.rst [new file with mode: 0644]
docs/Advent of Code 2017 December 6th.rst [new file with mode: 0644]
docs/Generator Programs.rst [new file with mode: 0644]
docs/Hylo-, Ana-, Cata-, and Para-morphisms - Recursion Combinators.rst [new file with mode: 0644]
docs/Newton-Raphson.rst [new file with mode: 0644]
docs/Quadratic.rst [new file with mode: 0644]
docs/Trees.rst [new file with mode: 0644]
docs/Zipper.rst [new file with mode: 0644]
joy/library.py
joy/pribrary.py [deleted file]

diff --git a/docs/0. This Implementation of Joy in Python.rst b/docs/0. This Implementation of Joy in Python.rst
new file mode 100644 (file)
index 0000000..7515dcc
--- /dev/null
@@ -0,0 +1,535 @@
+
+Joypy
+=====
+
+Joy in Python
+-------------
+
+This implementation is meant as a tool for exploring the programming
+model and method of Joy. Python seems like a great implementation
+language for Joy for several reasons.
+
+We can lean on the Python immutable types for our basic semantics and
+types: ints, floats, strings, and tuples, which enforces functional
+purity. We get garbage collection for free. Compilation via Cython. Glue
+language with loads of libraries.
+
+`Read-Eval-Print Loop (REPL) <https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop>`__
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The main way to interact with the Joy interpreter is through a simple
+`REPL <https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop>`__
+that you start by running the package:
+
+::
+
+    $ python -m joy
+    Joypy - Copyright © 2017 Simon Forman
+    This program comes with ABSOLUTELY NO WARRANTY; for details type "warranty".
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type "sharing" for details.
+    Type "words" to see a list of all words, and "[<name>] help" to print the
+    docs for a word.
+
+
+     <-top
+
+    joy? _
+
+The ``<-top`` marker points to the top of the (initially empty) stack.
+You can enter Joy notation at the prompt and a `trace of
+evaluation <#The-TracePrinter.>`__ will be printed followed by the stack
+and prompt again:
+
+::
+
+    joy? 23 sqr 18 +
+           . 23 sqr 18 +
+        23 . sqr 18 +
+        23 . dup mul 18 +
+     23 23 . mul 18 +
+       529 . 18 +
+    529 18 . +
+       547 . 
+
+    547 <-top
+
+    joy? 
+
+Stacks (aka list, quote, sequence, etc.)
+========================================
+
+In Joy, in addition to the types Boolean, integer, float, and string,
+there is a single sequence type represented by enclosing a sequence of
+terms in brackets ``[...]``. This sequence type is used to represent
+both the stack and the expression. It is a `cons
+list <https://en.wikipedia.org/wiki/Cons#Lists>`__ made from Python
+tuples.
+
+.. code:: ipython2
+
+    import inspect
+    import joy.utils.stack
+    
+    
+    print inspect.getdoc(joy.utils.stack)
+
+
+.. parsed-literal::
+
+    § Stack
+    
+    
+    When talking about Joy we use the terms "stack", "list", "sequence" and
+    "aggregate" to mean the same thing: a simple datatype that permits
+    certain operations such as iterating and pushing and popping values from
+    (at least) one end.
+    
+    We use the venerable two-tuple recursive form of sequences where the
+    empty tuple () is the empty stack and (head, rest) gives the recursive
+    form of a stack with one or more items on it.
+    
+      ()
+      (1, ())
+      (2, (1, ()))
+      (3, (2, (1, ())))
+      ...
+    
+    And so on.
+    
+    
+    We have two very simple functions to build up a stack from a Python
+    iterable and also to iterate through a stack and yield its items
+    one-by-one in order, and two functions to generate string representations
+    of stacks:
+    
+      list_to_stack()
+    
+      iter_stack()
+    
+      expression_to_string()  (prints left-to-right)
+    
+      stack_to_string()  (prints right-to-left)
+    
+    
+    A word about the stack data structure.
+    
+    Python has very nice "tuple packing and unpacking" in its syntax which
+    means we can directly "unpack" the expected arguments to a Joy function.
+    
+    For example:
+    
+      def dup(stack):
+        head, tail = stack
+        return head, (head, tail)
+    
+    We replace the argument "stack" by the expected structure of the stack,
+    in this case "(head, tail)", and Python takes care of de-structuring the
+    incoming argument and assigning values to the names.  Note that Python
+    syntax doesn't require parentheses around tuples used in expressions
+    where they would be redundant.
+
+
+The utility functions maintain order.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The 0th item in the list will be on the top of the stack and *vise
+versa*.
+
+.. code:: ipython2
+
+    joy.utils.stack.list_to_stack([1, 2, 3])
+
+
+
+
+.. parsed-literal::
+
+    (1, (2, (3, ())))
+
+
+
+.. code:: ipython2
+
+    list(joy.utils.stack.iter_stack((1, (2, (3, ())))))
+
+
+
+
+.. parsed-literal::
+
+    [1, 2, 3]
+
+
+
+This requires reversing the sequence (or iterating backwards) otherwise:
+
+.. code:: ipython2
+
+    stack = ()
+    
+    for n in [1, 2, 3]:
+        stack = n, stack
+    
+    print stack
+    print list(joy.utils.stack.iter_stack(stack))
+
+
+.. parsed-literal::
+
+    (3, (2, (1, ())))
+    [3, 2, 1]
+
+
+Purely Functional Datastructures.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Because Joy lists are made out of Python tuples they are immutable, so
+all Joy datastructures are *`purely
+functional <https://en.wikipedia.org/wiki/Purely_functional_data_structure>`__*.
+
+The ``joy()`` function.
+=======================
+
+An Interpreter
+--------------
+
+The ``joy()`` function is extrememly simple. It accepts a stack, an
+expression, and a dictionary, and it iterates through the expression
+putting values onto the stack and delegating execution to functions it
+looks up in the dictionary.
+
+Each function is passed the stack, expression, and dictionary and
+returns them. Whatever the function returns becomes the new stack,
+expression, and dictionary. (The dictionary is passed to enable e.g.
+writing words that let you enter new words into the dictionary at
+runtime, which nothing does yet and may be a bad idea, and the ``help``
+command.)
+
+.. code:: ipython2
+
+    import joy.joy
+    
+    print inspect.getsource(joy.joy.joy)
+
+
+.. parsed-literal::
+
+    def joy(stack, expression, dictionary, viewer=None):
+      '''
+      Evaluate the Joy expression on the stack.
+      '''
+      while expression:
+    
+        if viewer: viewer(stack, expression)
+    
+        term, expression = expression
+        if isinstance(term, Symbol):
+          term = dictionary[term]
+          stack, expression, dictionary = term(stack, expression, dictionary)
+        else:
+          stack = term, stack
+    
+      if viewer: viewer(stack, expression)
+      return stack, expression, dictionary
+    
+
+
+View function
+~~~~~~~~~~~~~
+
+The ``joy()`` function accepts a "viewer" function which it calls on
+each iteration passing the current stack and expression just before
+evaluation. This can be used for tracing, breakpoints, retrying after
+exceptions, or interrupting an evaluation and saving to disk or sending
+over the network to resume later. The stack and expression together
+contain all the state of the computation at each step.
+
+The ``TracePrinter``.
+~~~~~~~~~~~~~~~~~~~~~
+
+A ``viewer`` records each step of the evaluation of a Joy program. The
+``TracePrinter`` has a facility for printing out a trace of the
+evaluation, one line per step. Each step is aligned to the current
+interpreter position, signified by a period separating the stack on the
+left from the pending expression ("continuation") on the right.
+
+`Continuation-Passing Style <https://en.wikipedia.org/wiki/Continuation-passing_style>`__
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One day I thought, What happens if you rewrite Joy to use
+`CSP <https://en.wikipedia.org/wiki/Continuation-passing_style>`__? I
+made all the functions accept and return the expression as well as the
+stack and found that all the combinators could be rewritten to work by
+modifying the expression rather than making recursive calls to the
+``joy()`` function.
+
+Parser
+======
+
+.. code:: ipython2
+
+    import joy.parser
+    
+    print inspect.getdoc(joy.parser)
+
+
+.. parsed-literal::
+
+    § Converting text to a joy expression.
+    
+    This module exports a single function:
+    
+      text_to_expression(text)
+    
+    As well as a single Symbol class and a single Exception type:
+    
+      ParseError
+    
+    When supplied with a string this function returns a Python datastructure
+    that represents the Joy datastructure described by the text expression.
+    Any unbalanced square brackets will raise a ParseError.
+
+
+The parser is extremely simple, the undocumented ``re.Scanner`` class
+does most of the tokenizing work and then you just build the tuple
+structure out of the tokens. There's no Abstract Syntax Tree or anything
+like that.
+
+.. code:: ipython2
+
+    print inspect.getsource(joy.parser._parse)
+
+
+.. parsed-literal::
+
+    def _parse(tokens):
+      '''
+      Return a stack/list expression of the tokens.
+      '''
+      frame = []
+      stack = []
+      for tok in tokens:
+        if tok == '[':
+          stack.append(frame)
+          frame = []
+          stack[-1].append(frame)
+        elif tok == ']':
+          try:
+            frame = stack.pop()
+          except IndexError:
+            raise ParseError('One or more extra closing brackets.')
+          frame[-1] = list_to_stack(frame[-1])
+        else:
+          frame.append(tok)
+      if stack:
+        raise ParseError('One or more unclosed brackets.')
+      return list_to_stack(frame)
+    
+
+
+That's pretty much all there is to it.
+
+.. code:: ipython2
+
+    joy.parser.text_to_expression('1 2 3 4 5')  # A simple sequence.
+
+
+
+
+.. parsed-literal::
+
+    (1, (2, (3, (4, (5, ())))))
+
+
+
+.. code:: ipython2
+
+    joy.parser.text_to_expression('[1 2 3] 4 5')  # Three items, the first is a list with three items
+
+
+
+
+.. parsed-literal::
+
+    ((1, (2, (3, ()))), (4, (5, ())))
+
+
+
+.. code:: ipython2
+
+    joy.parser.text_to_expression('1 23 ["four" [-5.0] cons] 8888')  # A mixed bag. cons is
+                                                                     # a Symbol, no lookup at
+                                                                     # parse-time.  Haiku docs.
+
+
+
+
+.. parsed-literal::
+
+    (1, (23, (('four', ((-5.0, ()), (cons, ()))), (8888, ()))))
+
+
+
+.. code:: ipython2
+
+    joy.parser.text_to_expression('[][][][][]')  # Five empty lists.
+
+
+
+
+.. parsed-literal::
+
+    ((), ((), ((), ((), ((), ())))))
+
+
+
+.. code:: ipython2
+
+    joy.parser.text_to_expression('[[[[[]]]]]')  # Five nested lists.
+
+
+
+
+.. parsed-literal::
+
+    ((((((), ()), ()), ()), ()), ())
+
+
+
+Library
+=======
+
+The Joy library of functions (aka commands, or "words" after Forth
+usage) encapsulates all the actual functionality (no pun intended) of
+the Joy system. There are simple functions such as addition ``add`` (or
+``+``, the library module supports aliases), and combinators which
+provide control-flow and higher-order operations.
+
+.. code:: ipython2
+
+    import joy.library
+    
+    print ' '.join(sorted(joy.library.initialize()))
+
+
+.. parsed-literal::
+
+    != % & * *fraction *fraction0 + ++ - -- / < << <= <> = > >= >> ? ^ add anamorphism and app1 app2 app3 average b binary branch choice clear cleave concat cons dinfrirst dip dipd dipdd disenstacken div down_to_zero dudipd dup dupd dupdip enstacken eq first flatten floordiv gcd ge genrec getitem gt help i id ifte infra le least_fraction loop lshift lt map min mod modulus mul ne neg not nullary or over pam parse pm pop popd popdd popop pow pred primrec product quoted range range_to_zero rem remainder remove rest reverse roll< roll> rolldown rollup rshift run second select sharing shunt size sqr sqrt stack step sub succ sum swaack swap swoncat swons ternary third times truediv truthy tuck unary uncons unit unquoted unstack void warranty while words x xor zip •
+
+
+Many of the functions are defined in Python, like ``dip``:
+
+.. code:: ipython2
+
+    print inspect.getsource(joy.library.dip)
+
+
+.. parsed-literal::
+
+    def dip(stack, expression, dictionary):
+      (quote, (x, stack)) = stack
+      expression = x, expression
+      return stack, pushback(quote, expression), dictionary
+    
+
+
+Some functions are defined in equations in terms of other functions.
+When the interpreter executes a definition function that function just
+pushes its body expression onto the pending expression (the
+continuation) and returns control to the interpreter.
+
+.. code:: ipython2
+
+    print joy.library.definitions
+
+
+.. parsed-literal::
+
+    second == rest first
+    third == rest rest first
+    product == 1 swap [*] step
+    swons == swap cons
+    swoncat == swap concat
+    flatten == [] swap [concat] step
+    unit == [] cons
+    quoted == [unit] dip
+    unquoted == [i] dip
+    enstacken == stack [clear] dip
+    disenstacken == ? [uncons ?] loop pop
+    ? == dup truthy
+    dinfrirst == dip infra first
+    nullary == [stack] dinfrirst
+    unary == [stack [pop] dip] dinfrirst
+    binary == [stack [popop] dip] dinfrirst
+    ternary == [stack [popop pop] dip] dinfrirst
+    pam == [i] map
+    run == [] swap infra
+    sqr == dup mul
+    size == 0 swap [pop ++] step
+    cleave == [i] app2 [popd] dip
+    average == [sum 1.0 *] [size] cleave /
+    gcd == 1 [tuck modulus dup 0 >] loop pop
+    least_fraction == dup [gcd] infra [div] concat map
+    *fraction == [uncons] dip uncons [swap] dip concat [*] infra [*] dip cons
+    *fraction0 == concat [[swap] dip * [*] dip] infra
+    down_to_zero == [0 >] [dup --] while
+    range_to_zero == unit [down_to_zero] infra
+    anamorphism == [pop []] swap [dip swons] genrec
+    range == [0 <=] [1 - dup] anamorphism
+    while == swap [nullary] cons dup dipd concat loop
+    dudipd == dup dipd
+    primrec == [i] genrec
+    
+
+
+Currently, there's no function to add new definitions to the dictionary
+from "within" Joy code itself. Adding new definitions remains a
+meta-interpreter action. You have to do it yourself, in Python, and wash
+your hands afterward.
+
+It would be simple enough to define one, but it would open the door to
+*name binding* and break the idea that all state is captured in the
+stack and expression. There's an implicit *standard dictionary* that
+defines the actual semantics of the syntactic stack and expression
+datastructures (which only contain symbols, not the actual functions.
+Pickle some and see for yourself.)
+
+"There should be only one."
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Which brings me to talking about one of my hopes and dreams for this
+notation: "There should be only one." What I mean is that there should
+be one universal standard dictionary of commands, and all bespoke work
+done in a UI for purposes takes place by direct interaction and macros.
+There would be a *Grand Refactoring* biannually (two years, not six
+months, that's semi-annually) where any new definitions factored out of
+the usage and macros of the previous time, along with new algorithms and
+such, were entered into the dictionary and posted to e.g. IPFS.
+
+Code should not burgeon wildly, as it does today. The variety of code
+should map more-or-less to the well-factored variety of human
+computably-solvable problems. There shouldn't be dozens of chat apps, JS
+frameworks, programming languages. It's a waste of time, a `fractal
+"thundering herd"
+attack <https://en.wikipedia.org/wiki/Thundering_herd_problem>`__ on
+human mentality.
+
+Literary Code Library
+^^^^^^^^^^^^^^^^^^^^^
+
+If you read over the other notebooks you'll see that developing code in
+Joy is a lot like doing simple mathematics, and the descriptions of the
+code resemble math papers. The code also works the first time, no bugs.
+If you have any experience programming at all, you are probably
+skeptical, as I was, but it seems to work: deriving code mathematically
+seems to lead to fewer errors.
+
+But my point now is that this great ratio of textual explanation to wind
+up with code that consists of a few equations and could fit on an index
+card is highly desirable. Less code has fewer errors. The structure of
+Joy engenders a kind of thinking that seems to be very effective for
+developing structured processes.
+
+There seems to be an elegance and power to the notation.
+
diff --git a/docs/1. Basic Use of Joy in a Notebook.rst b/docs/1. Basic Use of Joy in a Notebook.rst
new file mode 100644 (file)
index 0000000..15f23e3
--- /dev/null
@@ -0,0 +1,154 @@
+
+Preamble
+~~~~~~~~
+
+First, import what we need.
+
+.. code:: ipython2
+
+    from joy.joy import run
+    from joy.library import initialize
+    from joy.utils.stack import stack_to_string
+    from joy.utils.pretty_print import TracePrinter
+
+Define a dictionary, an initial stack, and two helper functions to run
+Joy code and print results for us.
+
+.. code:: ipython2
+
+    D = initialize()
+    S = ()
+    
+    
+    def J(text):
+        print stack_to_string(run(text, S, D)[0])
+    
+    
+    def V(text):
+        tp = TracePrinter()
+        run(text, S, D, tp.viewer)
+        tp.print_()
+
+Run some simple programs
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 18 +')
+
+
+.. parsed-literal::
+
+    41
+
+
+.. code:: ipython2
+
+    J('45 30 gcd')
+
+
+.. parsed-literal::
+
+    15
+
+
+With Viewer
+~~~~~~~~~~~
+
+A ``viewer`` records each step of the evaluation of a Joy program. The
+``TracePrinter`` has a facility for printing out a trace of the
+evaluation, one line per step. Each step is aligned to the current
+interpreter position, signified by a period separating the stack on the
+left from the pending expression ("continuation") on the right. I find
+these traces beautiful, like a kind of art.
+
+.. code:: ipython2
+
+    V('23 18 +')
+
+
+.. parsed-literal::
+
+          . 23 18 +
+       23 . 18 +
+    23 18 . +
+       41 . 
+
+
+.. code:: ipython2
+
+    V('45 30 gcd')
+
+
+.. parsed-literal::
+
+                                      . 45 30 gcd
+                                   45 . 30 gcd
+                                45 30 . gcd
+                                45 30 . 1 [tuck modulus dup 0 >] loop pop
+                              45 30 1 . [tuck modulus dup 0 >] loop pop
+       45 30 1 [tuck modulus dup 0 >] . loop pop
+                                45 30 . tuck modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                             30 45 30 . modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                                30 15 . dup 0 > [tuck modulus dup 0 >] loop pop
+                             30 15 15 . 0 > [tuck modulus dup 0 >] loop pop
+                           30 15 15 0 . > [tuck modulus dup 0 >] loop pop
+                           30 15 True . [tuck modulus dup 0 >] loop pop
+    30 15 True [tuck modulus dup 0 >] . loop pop
+                                30 15 . tuck modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                             15 30 15 . modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                                 15 0 . dup 0 > [tuck modulus dup 0 >] loop pop
+                               15 0 0 . 0 > [tuck modulus dup 0 >] loop pop
+                             15 0 0 0 . > [tuck modulus dup 0 >] loop pop
+                           15 0 False . [tuck modulus dup 0 >] loop pop
+    15 0 False [tuck modulus dup 0 >] . loop pop
+                                 15 0 . pop
+                                   15 . 
+
+
+Here's a longer trace.
+
+.. code:: ipython2
+
+    V('96 27 gcd')
+
+
+.. parsed-literal::
+
+                                      . 96 27 gcd
+                                   96 . 27 gcd
+                                96 27 . gcd
+                                96 27 . 1 [tuck modulus dup 0 >] loop pop
+                              96 27 1 . [tuck modulus dup 0 >] loop pop
+       96 27 1 [tuck modulus dup 0 >] . loop pop
+                                96 27 . tuck modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                             27 96 27 . modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                                27 15 . dup 0 > [tuck modulus dup 0 >] loop pop
+                             27 15 15 . 0 > [tuck modulus dup 0 >] loop pop
+                           27 15 15 0 . > [tuck modulus dup 0 >] loop pop
+                           27 15 True . [tuck modulus dup 0 >] loop pop
+    27 15 True [tuck modulus dup 0 >] . loop pop
+                                27 15 . tuck modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                             15 27 15 . modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                                15 12 . dup 0 > [tuck modulus dup 0 >] loop pop
+                             15 12 12 . 0 > [tuck modulus dup 0 >] loop pop
+                           15 12 12 0 . > [tuck modulus dup 0 >] loop pop
+                           15 12 True . [tuck modulus dup 0 >] loop pop
+    15 12 True [tuck modulus dup 0 >] . loop pop
+                                15 12 . tuck modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                             12 15 12 . modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                                 12 3 . dup 0 > [tuck modulus dup 0 >] loop pop
+                               12 3 3 . 0 > [tuck modulus dup 0 >] loop pop
+                             12 3 3 0 . > [tuck modulus dup 0 >] loop pop
+                            12 3 True . [tuck modulus dup 0 >] loop pop
+     12 3 True [tuck modulus dup 0 >] . loop pop
+                                 12 3 . tuck modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                               3 12 3 . modulus dup 0 > [tuck modulus dup 0 >] loop pop
+                                  3 0 . dup 0 > [tuck modulus dup 0 >] loop pop
+                                3 0 0 . 0 > [tuck modulus dup 0 >] loop pop
+                              3 0 0 0 . > [tuck modulus dup 0 >] loop pop
+                            3 0 False . [tuck modulus dup 0 >] loop pop
+     3 0 False [tuck modulus dup 0 >] . loop pop
+                                  3 0 . pop
+                                    3 . 
+
diff --git a/docs/2. Library Examples.rst b/docs/2. Library Examples.rst
new file mode 100644 (file)
index 0000000..6ffa7e8
--- /dev/null
@@ -0,0 +1,1762 @@
+
+Examples (and some documentation) for the Words in the Library
+==============================================================
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V
+
+Stack Chatter
+=============
+
+This is what I like to call the functions that just rearrange things on
+the stack. (One thing I want to mention is that during a hypothetical
+compilation phase these "stack chatter" words effectively disappear,
+because we can map the logical stack locations to registers that remain
+static for the duration of the computation. This remains to be done but
+it's "off the shelf" technology.)
+
+``clear``
+~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 2 3 clear')
+    J('1 2 3 clear')
+
+
+.. parsed-literal::
+
+    ...
+
+
+``dup`` ``dupd``
+~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 2 3 dup')
+
+
+.. parsed-literal::
+
+    1 2 3 3
+
+
+.. code:: ipython2
+
+    J('1 2 3 dupd')
+
+
+.. parsed-literal::
+
+    1 2 2 3
+
+
+``enstacken`` ``disenstacken`` ``stack`` ``unstack``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(I may have these paired up wrong. I.e. ``disenstacken`` should be
+``unstack`` and vice versa.)
+
+.. code:: ipython2
+
+    J('1 2 3 enstacken') # Replace the stack with a quote of itself.
+
+
+.. parsed-literal::
+
+    [3 2 1]
+
+
+.. code:: ipython2
+
+    J('4 5 6 [3 2 1] disenstacken')  # Unpack a list onto the stack.
+
+
+.. parsed-literal::
+
+    4 5 6 3 2 1
+
+
+.. code:: ipython2
+
+    J('1 2 3 stack')  # Get the stack on the stack.
+
+
+.. parsed-literal::
+
+    1 2 3 [3 2 1]
+
+
+.. code:: ipython2
+
+    J('1 2 3 [4 5 6] unstack')  # Replace the stack with the list on top.
+                                # The items appear reversed but they are not,
+                                # 4 is on the top of both the list and the stack.
+
+
+.. parsed-literal::
+
+    6 5 4
+
+
+``pop`` ``popd`` ``popop``
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 2 3 pop')
+
+
+.. parsed-literal::
+
+    1 2
+
+
+.. code:: ipython2
+
+    J('1 2 3 popd')
+
+
+.. parsed-literal::
+
+    1 3
+
+
+.. code:: ipython2
+
+    J('1 2 3 popop')
+
+
+.. parsed-literal::
+
+    1
+
+
+``roll<`` ``rolldown`` ``roll>`` ``rollup``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The "down" and "up" refer to the movement of two of the top three items
+(displacing the third.)
+
+.. code:: ipython2
+
+    J('1 2 3 roll<')
+
+
+.. parsed-literal::
+
+    2 3 1
+
+
+.. code:: ipython2
+
+    J('1 2 3 roll>')
+
+
+.. parsed-literal::
+
+    3 1 2
+
+
+``swap``
+~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 2 3 swap')
+
+
+.. parsed-literal::
+
+    1 3 2
+
+
+``tuck`` ``over``
+~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 2 3 tuck')
+
+
+.. parsed-literal::
+
+    1 3 2 3
+
+
+.. code:: ipython2
+
+    J('1 2 3 over')
+
+
+.. parsed-literal::
+
+    1 2 3 2
+
+
+``unit`` ``quoted`` ``unquoted``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 2 3 unit')
+
+
+.. parsed-literal::
+
+    1 2 [3]
+
+
+.. code:: ipython2
+
+    J('1 2 3 quoted')
+
+
+.. parsed-literal::
+
+    1 [2] 3
+
+
+.. code:: ipython2
+
+    J('1 [2] 3 unquoted')
+
+
+.. parsed-literal::
+
+    1 2 3
+
+
+.. code:: ipython2
+
+    V('1 [dup] 3 unquoted')  # Unquoting evaluates.  Be aware.
+
+
+.. parsed-literal::
+
+                  . 1 [dup] 3 unquoted
+                1 . [dup] 3 unquoted
+          1 [dup] . 3 unquoted
+        1 [dup] 3 . unquoted
+        1 [dup] 3 . [i] dip
+    1 [dup] 3 [i] . dip
+          1 [dup] . i 3
+                1 . dup 3
+              1 1 . 3
+            1 1 3 . 
+
+
+List words
+==========
+
+``concat`` ``swoncat`` ``shunt``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 2 3] [4 5 6] concat')
+
+
+.. parsed-literal::
+
+    [1 2 3 4 5 6]
+
+
+.. code:: ipython2
+
+    J('[1 2 3] [4 5 6] swoncat')
+
+
+.. parsed-literal::
+
+    [4 5 6 1 2 3]
+
+
+.. code:: ipython2
+
+    J('[1 2 3] [4 5 6] shunt')
+
+
+.. parsed-literal::
+
+    [6 5 4 1 2 3]
+
+
+``cons`` ``swons`` ``uncons``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 [2 3] cons')
+
+
+.. parsed-literal::
+
+    [1 2 3]
+
+
+.. code:: ipython2
+
+    J('[2 3] 1 swons')
+
+
+.. parsed-literal::
+
+    [1 2 3]
+
+
+.. code:: ipython2
+
+    J('[1 2 3] uncons')
+
+
+.. parsed-literal::
+
+    1 [2 3]
+
+
+``first`` ``second`` ``third`` ``rest``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 2 3 4] first')
+
+
+.. parsed-literal::
+
+    1
+
+
+.. code:: ipython2
+
+    J('[1 2 3 4] second')
+
+
+.. parsed-literal::
+
+    2
+
+
+.. code:: ipython2
+
+    J('[1 2 3 4] third')
+
+
+.. parsed-literal::
+
+    3
+
+
+.. code:: ipython2
+
+    J('[1 2 3 4] rest')
+
+
+.. parsed-literal::
+
+    [2 3 4]
+
+
+``flatten``
+~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[[1] [2 [3] 4] [5 6]] flatten')
+
+
+.. parsed-literal::
+
+    [1 2 [3] 4 5 6]
+
+
+``getitem`` ``at`` ``of`` ``drop`` ``take``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``at`` and ``getitem`` are the same function. ``of == swap at``
+
+.. code:: ipython2
+
+    J('[10 11 12 13 14] 2 getitem')
+
+
+.. parsed-literal::
+
+    12
+
+
+.. code:: ipython2
+
+    J('[1 2 3 4] 0 at')
+
+
+.. parsed-literal::
+
+    1
+
+
+.. code:: ipython2
+
+    J('2 [1 2 3 4] of')
+
+
+.. parsed-literal::
+
+    3
+
+
+.. code:: ipython2
+
+    J('[1 2 3 4] 2 drop')
+
+
+.. parsed-literal::
+
+    [3 4]
+
+
+.. code:: ipython2
+
+    J('[1 2 3 4] 2 take')  # reverses the order
+
+
+.. parsed-literal::
+
+    [2 1]
+
+
+``reverse`` could be defines as ``reverse == dup size take``
+
+``remove``
+~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 2 3 1 4] 1 remove')
+
+
+.. parsed-literal::
+
+    [2 3 1 4]
+
+
+``reverse``
+~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 2 3 4] reverse')
+
+
+.. parsed-literal::
+
+    [4 3 2 1]
+
+
+``size``
+~~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 1 1 1] size')
+
+
+.. parsed-literal::
+
+    4
+
+
+``swaack``
+~~~~~~~~~~
+
+"Swap stack" swap the list on the top of the stack for the stack, and
+put the old stack on top of the new one. Think of it as a context
+switch. Niether of the lists/stacks change their order.
+
+.. code:: ipython2
+
+    J('1 2 3 [4 5 6] swaack')
+
+
+.. parsed-literal::
+
+    6 5 4 [3 2 1]
+
+
+``choice`` ``select``
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 9 1 choice')
+
+
+.. parsed-literal::
+
+    9
+
+
+.. code:: ipython2
+
+    J('23 9 0 choice')
+
+
+.. parsed-literal::
+
+    23
+
+
+.. code:: ipython2
+
+    J('[23 9 7] 1 select')  # select is basically getitem, should retire it?
+
+
+.. parsed-literal::
+
+    9
+
+
+.. code:: ipython2
+
+    J('[23 9 7] 0 select')
+
+
+.. parsed-literal::
+
+    23
+
+
+``zip``
+~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 2 3] [6 5 4] zip')
+
+
+.. parsed-literal::
+
+    [[6 1] [5 2] [4 3]]
+
+
+.. code:: ipython2
+
+    J('[1 2 3] [6 5 4] zip [sum] map')
+
+
+.. parsed-literal::
+
+    [7 7 7]
+
+
+Math words
+==========
+
+``+`` ``add``
+~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 9 +')
+
+
+.. parsed-literal::
+
+    32
+
+
+``-`` ``sub``
+~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 9 -')
+
+
+.. parsed-literal::
+
+    14
+
+
+``*`` ``mul``
+~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 9 *')
+
+
+.. parsed-literal::
+
+    207
+
+
+``/`` ``div`` ``floordiv`` ``truediv``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 9 /')
+
+
+.. parsed-literal::
+
+    2.5555555555555554
+
+
+.. code:: ipython2
+
+    J('23 -9 truediv')
+
+
+.. parsed-literal::
+
+    -2.5555555555555554
+
+
+.. code:: ipython2
+
+    J('23 9 div')
+
+
+.. parsed-literal::
+
+    2
+
+
+.. code:: ipython2
+
+    J('23 9 floordiv')
+
+
+.. parsed-literal::
+
+    2
+
+
+.. code:: ipython2
+
+    J('23 -9 div')
+
+
+.. parsed-literal::
+
+    -3
+
+
+.. code:: ipython2
+
+    J('23 -9 floordiv')
+
+
+.. parsed-literal::
+
+    -3
+
+
+``%`` ``mod`` ``modulus`` ``rem`` ``remainder``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 9 %')
+
+
+.. parsed-literal::
+
+    5
+
+
+``neg``
+~~~~~~~
+
+.. code:: ipython2
+
+    J('23 neg -5 neg')
+
+
+.. parsed-literal::
+
+    -23 5
+
+
+pow
+~~~
+
+.. code:: ipython2
+
+    J('2 10 pow')
+
+
+.. parsed-literal::
+
+    1024
+
+
+``sqr`` ``sqrt``
+~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 sqr')
+
+
+.. parsed-literal::
+
+    529
+
+
+.. code:: ipython2
+
+    J('23 sqrt')
+
+
+.. parsed-literal::
+
+    4.795831523312719
+
+
+``++`` ``succ`` ``--`` ``pred``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 ++')
+
+
+.. parsed-literal::
+
+    2
+
+
+.. code:: ipython2
+
+    J('1 --')
+
+
+.. parsed-literal::
+
+    0
+
+
+``<<`` ``lshift`` ``>>`` ``rshift``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('8 1 <<')
+
+
+.. parsed-literal::
+
+    16
+
+
+.. code:: ipython2
+
+    J('8 1 >>')
+
+
+.. parsed-literal::
+
+    4
+
+
+``average``
+~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 2 3 5] average')
+
+
+.. parsed-literal::
+
+    2.75
+
+
+``range`` ``range_to_zero`` ``down_to_zero``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('5 range')
+
+
+.. parsed-literal::
+
+    [4 3 2 1 0]
+
+
+.. code:: ipython2
+
+    J('5 range_to_zero')
+
+
+.. parsed-literal::
+
+    [0 1 2 3 4 5]
+
+
+.. code:: ipython2
+
+    J('5 down_to_zero')
+
+
+.. parsed-literal::
+
+    5 4 3 2 1 0
+
+
+``product``
+~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 2 3 5] product')
+
+
+.. parsed-literal::
+
+    30
+
+
+``sum``
+~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 2 3 5] sum')
+
+
+.. parsed-literal::
+
+    11
+
+
+``min``
+~~~~~~~
+
+.. code:: ipython2
+
+    J('[1 2 3 5] min')
+
+
+.. parsed-literal::
+
+    1
+
+
+``gcd``
+~~~~~~~
+
+.. code:: ipython2
+
+    J('45 30 gcd')
+
+
+.. parsed-literal::
+
+    15
+
+
+``least_fraction``
+~~~~~~~~~~~~~~~~~~
+
+If we represent fractions as a quoted pair of integers [q d] this word
+reduces them to their ... least common factors or whatever.
+
+.. code:: ipython2
+
+    J('[45 30] least_fraction')
+
+
+.. parsed-literal::
+
+    [3 2]
+
+
+.. code:: ipython2
+
+    J('[23 12] least_fraction')
+
+
+.. parsed-literal::
+
+    [23 12]
+
+
+Logic and Comparison
+====================
+
+``?`` ``truthy``
+~~~~~~~~~~~~~~~~
+
+Get the Boolean value of the item on the top of the stack.
+
+.. code:: ipython2
+
+    J('23 truthy')
+
+
+.. parsed-literal::
+
+    True
+
+
+.. code:: ipython2
+
+    J('[] truthy')  # Python semantics.
+
+
+.. parsed-literal::
+
+    False
+
+
+.. code:: ipython2
+
+    J('0 truthy')
+
+
+.. parsed-literal::
+
+    False
+
+
+::
+
+    ? == dup truthy
+
+.. code:: ipython2
+
+    V('23 ?')
+
+
+.. parsed-literal::
+
+            . 23 ?
+         23 . ?
+         23 . dup truthy
+      23 23 . truthy
+    23 True . 
+
+
+.. code:: ipython2
+
+    J('[] ?')
+
+
+.. parsed-literal::
+
+    [] False
+
+
+.. code:: ipython2
+
+    J('0 ?')
+
+
+.. parsed-literal::
+
+    0 False
+
+
+``&`` ``and``
+~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 9 &')
+
+
+.. parsed-literal::
+
+    1
+
+
+``!=`` ``<>`` ``ne``
+~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('23 9 !=')
+
+
+.. parsed-literal::
+
+    True
+
+
+| The usual suspects: - ``<`` ``lt`` - ``<=`` ``le``
+| - ``=`` ``eq`` - ``>`` ``gt`` - ``>=`` ``ge`` - ``not`` - ``or``
+
+``^`` ``xor``
+~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 1 ^')
+
+
+.. parsed-literal::
+
+    0
+
+
+.. code:: ipython2
+
+    J('1 0 ^')
+
+
+.. parsed-literal::
+
+    1
+
+
+Miscellaneous
+=============
+
+``help``
+~~~~~~~~
+
+.. code:: ipython2
+
+    J('[help] help')
+
+
+.. parsed-literal::
+
+    Accepts a quoted symbol on the top of the stack and prints its docs.
+    
+
+
+``parse``
+~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[parse] help')
+
+
+.. parsed-literal::
+
+    Parse the string on the stack to a Joy expression.
+    
+
+
+.. code:: ipython2
+
+    J('1 "2 [3] dup" parse')
+
+
+.. parsed-literal::
+
+    1 [2 [3] dup]
+
+
+``run``
+~~~~~~~
+
+Evaluate a quoted Joy sequence.
+
+.. code:: ipython2
+
+    J('[1 2 dup + +] run')
+
+
+.. parsed-literal::
+
+    [5]
+
+
+Combinators
+===========
+
+``app1`` ``app2`` ``app3``
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[app1] help')
+
+
+.. parsed-literal::
+
+    Given a quoted program on TOS and anything as the second stack item run
+    the program and replace the two args with the first result of the
+    program.
+    
+                ... x [Q] . app1
+       -----------------------------------
+          ... [x ...] [Q] . infra first
+    
+
+
+.. code:: ipython2
+
+    J('10 4 [sqr *] app1')
+
+
+.. parsed-literal::
+
+    10 160
+
+
+.. code:: ipython2
+
+    J('10 3 4 [sqr *] app2')
+
+
+.. parsed-literal::
+
+    10 90 160
+
+
+.. code:: ipython2
+
+    J('[app2] help')
+
+
+.. parsed-literal::
+
+    Like app1 with two items.
+    
+           ... y x [Q] . app2
+    -----------------------------------
+       ... [y ...] [Q] . infra first
+           [x ...] [Q]   infra first
+    
+
+
+.. code:: ipython2
+
+    J('10 2 3 4 [sqr *] app3')
+
+
+.. parsed-literal::
+
+    10 40 90 160
+
+
+``anamorphism``
+~~~~~~~~~~~~~~~
+
+Given an initial value, a predicate function ``[P]``, and a generator
+function ``[G]``, the ``anamorphism`` combinator creates a sequence.
+
+::
+
+       n [P] [G] anamorphism
+    ---------------------------
+              [...]
+
+Example, ``range``:
+
+::
+
+    range == [0 <=] [1 - dup] anamorphism
+
+.. code:: ipython2
+
+    J('3 [0 <=] [1 - dup] anamorphism')
+
+
+.. parsed-literal::
+
+    [2 1 0]
+
+
+``branch``
+~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('3 4 1 [+] [*] branch')
+
+
+.. parsed-literal::
+
+    12
+
+
+.. code:: ipython2
+
+    J('3 4 0 [+] [*] branch')
+
+
+.. parsed-literal::
+
+    7
+
+
+``cleave``
+~~~~~~~~~~
+
+::
+
+    ... x [P] [Q] cleave
+
+From the original Joy docs: "The cleave combinator expects two
+quotations, and below that an item ``x`` It first executes ``[P]``, with
+``x`` on top, and saves the top result element. Then it executes
+``[Q]``, again with ``x``, and saves the top result. Finally it restores
+the stack to what it was below ``x`` and pushes the two results P(X) and
+Q(X)."
+
+Note that ``P`` and ``Q`` can use items from the stack freely, since the
+stack (below ``x``) is restored. ``cleave`` is a kind of *parallel*
+primitive, and it would make sense to create a version that uses, e.g.
+Python threads or something, to actually run ``P`` and ``Q``
+concurrently. The current implementation of ``cleave`` is a definition
+in terms of ``app2``:
+
+::
+
+    cleave == [i] app2 [popd] dip
+
+.. code:: ipython2
+
+    J('10 2 [+] [-] cleave')
+
+
+.. parsed-literal::
+
+    10 12 8
+
+
+``dip`` ``dipd`` ``dipdd``
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 2 3 4 5 [+] dip')
+
+
+.. parsed-literal::
+
+    1 2 7 5
+
+
+.. code:: ipython2
+
+    J('1 2 3 4 5 [+] dipd')
+
+
+.. parsed-literal::
+
+    1 5 4 5
+
+
+.. code:: ipython2
+
+    J('1 2 3 4 5 [+] dipdd')
+
+
+.. parsed-literal::
+
+    3 3 4 5
+
+
+``dupdip``
+~~~~~~~~~~
+
+Expects a quoted program ``[Q]`` on the stack and some item under it,
+``dup`` the item and ``dip`` the quoted program under it.
+
+::
+
+    n [Q] dupdip == n Q n
+
+.. code:: ipython2
+
+    V('23 [++] dupdip *')  # N(N + 1)
+
+
+.. parsed-literal::
+
+            . 23 [++] dupdip *
+         23 . [++] dupdip *
+    23 [++] . dupdip *
+         23 . ++ 23 *
+         24 . 23 *
+      24 23 . *
+        552 . 
+
+
+``genrec`` ``primrec``
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[genrec] help')
+
+
+.. parsed-literal::
+
+    General Recursion Combinator.
+    
+                            [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."
+    
+    The way to design one of these is to fix your base case [then] and the
+    test [if], and then treat rec1 and rec2 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
+    
+    If the [I] if-part fails you must derive R1 and R2 from:
+    
+        ... R1 [F] R2
+    
+    Just 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.  In effect, the
+    genrec combinator turns into an ifte combinator with a quoted copy of
+    the original definition in the else-part:
+    
+        F == [I] [T] [R1]   [R2] genrec
+          == [I] [T] [R1 [F] R2] ifte
+    
+    (Primitive recursive functions are those where R2 == i.
+    
+        P == [I] [T] [R] primrec
+          == [I] [T] [R [P] i] ifte
+          == [I] [T] [R P] ifte
+    )
+    
+
+
+.. code:: ipython2
+
+    J('3 [1 <=] [] [dup --] [i *] genrec')
+
+
+.. parsed-literal::
+
+    6
+
+
+``i``
+~~~~~
+
+.. code:: ipython2
+
+    V('1 2 3 [+ +] i')
+
+
+.. parsed-literal::
+
+                . 1 2 3 [+ +] i
+              1 . 2 3 [+ +] i
+            1 2 . 3 [+ +] i
+          1 2 3 . [+ +] i
+    1 2 3 [+ +] . i
+          1 2 3 . + +
+            1 5 . +
+              6 . 
+
+
+``ifte``
+~~~~~~~~
+
+::
+
+    [predicate] [then] [else] ifte
+
+.. code:: ipython2
+
+    J('1 2 [1] [+] [*] ifte')
+
+
+.. parsed-literal::
+
+    3
+
+
+.. code:: ipython2
+
+    J('1 2 [0] [+] [*] ifte')
+
+
+.. parsed-literal::
+
+    2
+
+
+``infra``
+~~~~~~~~~
+
+.. code:: ipython2
+
+    V('1 2 3 [4 5 6] [* +] infra')
+
+
+.. parsed-literal::
+
+                        . 1 2 3 [4 5 6] [* +] infra
+                      1 . 2 3 [4 5 6] [* +] infra
+                    1 2 . 3 [4 5 6] [* +] infra
+                  1 2 3 . [4 5 6] [* +] infra
+          1 2 3 [4 5 6] . [* +] infra
+    1 2 3 [4 5 6] [* +] . infra
+                  6 5 4 . * + [3 2 1] swaack
+                   6 20 . + [3 2 1] swaack
+                     26 . [3 2 1] swaack
+             26 [3 2 1] . swaack
+             1 2 3 [26] . 
+
+
+``loop``
+~~~~~~~~
+
+.. code:: ipython2
+
+    J('[loop] help')
+
+
+.. parsed-literal::
+
+    Basic loop combinator.
+    
+       ... True [Q] loop
+    -----------------------
+         ... Q [Q] loop
+    
+       ... False [Q] loop
+    ------------------------
+              ...
+    
+
+
+.. code:: ipython2
+
+    V('3 dup [1 - dup] loop')
+
+
+.. parsed-literal::
+
+                  . 3 dup [1 - dup] loop
+                3 . dup [1 - dup] loop
+              3 3 . [1 - dup] loop
+    3 3 [1 - dup] . loop
+                3 . 1 - dup [1 - dup] loop
+              3 1 . - dup [1 - dup] loop
+                2 . dup [1 - dup] loop
+              2 2 . [1 - dup] loop
+    2 2 [1 - dup] . loop
+                2 . 1 - dup [1 - dup] loop
+              2 1 . - dup [1 - dup] loop
+                1 . dup [1 - dup] loop
+              1 1 . [1 - dup] loop
+    1 1 [1 - dup] . loop
+                1 . 1 - dup [1 - dup] loop
+              1 1 . - dup [1 - dup] loop
+                0 . dup [1 - dup] loop
+              0 0 . [1 - dup] loop
+    0 0 [1 - dup] . loop
+                0 . 
+
+
+``map`` ``pam``
+~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('10 [1 2 3] [*] map')
+
+
+.. parsed-literal::
+
+    10 [10 20 30]
+
+
+.. code:: ipython2
+
+    J('10 5 [[*][/][+][-]] pam')
+
+
+.. parsed-literal::
+
+    10 5 [50 2.0 15 5]
+
+
+``nullary`` ``unary`` ``binary`` ``ternary``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Run a quoted program enforcing
+`arity <https://en.wikipedia.org/wiki/Arity>`__.
+
+.. code:: ipython2
+
+    J('1 2 3 4 5 [+] nullary')
+
+
+.. parsed-literal::
+
+    1 2 3 4 5 9
+
+
+.. code:: ipython2
+
+    J('1 2 3 4 5 [+] unary')
+
+
+.. parsed-literal::
+
+    1 2 3 4 9
+
+
+.. code:: ipython2
+
+    J('1 2 3 4 5 [+] binary')  # + has arity 2 so this is technically pointless...
+
+
+.. parsed-literal::
+
+    1 2 3 9
+
+
+.. code:: ipython2
+
+    J('1 2 3 4 5 [+] ternary')
+
+
+.. parsed-literal::
+
+    1 2 9
+
+
+``step``
+~~~~~~~~
+
+.. 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
+
+    V('0 [1 2 3] [+] step')
+
+
+.. parsed-literal::
+
+                  . 0 [1 2 3] [+] step
+                0 . [1 2 3] [+] step
+        0 [1 2 3] . [+] step
+    0 [1 2 3] [+] . step
+          0 1 [+] . i [2 3] [+] step
+              0 1 . + [2 3] [+] step
+                1 . [2 3] [+] step
+          1 [2 3] . [+] step
+      1 [2 3] [+] . step
+          1 2 [+] . i [3] [+] step
+              1 2 . + [3] [+] step
+                3 . [3] [+] step
+            3 [3] . [+] step
+        3 [3] [+] . step
+          3 3 [+] . i
+              3 3 . +
+                6 . 
+
+
+``times``
+~~~~~~~~~
+
+.. code:: ipython2
+
+    V('3 2 1 2 [+] times')
+
+
+.. parsed-literal::
+
+                . 3 2 1 2 [+] times
+              3 . 2 1 2 [+] times
+            3 2 . 1 2 [+] times
+          3 2 1 . 2 [+] times
+        3 2 1 2 . [+] times
+    3 2 1 2 [+] . times
+          3 2 1 . + 1 [+] times
+            3 3 . 1 [+] times
+          3 3 1 . [+] times
+      3 3 1 [+] . times
+            3 3 . +
+              6 . 
+
+
+``b``
+~~~~~
+
+.. code:: ipython2
+
+    J('[b] help')
+
+
+.. parsed-literal::
+
+    b == [i] dip i
+    
+    ... [P] [Q] b == ... [P] i [Q] i
+    ... [P] [Q] b == ... P Q
+    
+
+
+.. code:: ipython2
+
+    V('1 2 [3] [4] b')
+
+
+.. parsed-literal::
+
+                . 1 2 [3] [4] b
+              1 . 2 [3] [4] b
+            1 2 . [3] [4] b
+        1 2 [3] . [4] b
+    1 2 [3] [4] . b
+            1 2 . 3 4
+          1 2 3 . 4
+        1 2 3 4 . 
+
+
+``while``
+~~~~~~~~~
+
+::
+
+    [predicate] [body] while
+
+.. code:: ipython2
+
+    J('3 [0 >] [dup --] while')
+
+
+.. parsed-literal::
+
+    3 2 1 0
+
+
+``x``
+~~~~~
+
+.. code:: ipython2
+
+    J('[x] help')
+
+
+.. parsed-literal::
+
+    x == dup i
+    
+    ... [Q] x = ... [Q] dup i
+    ... [Q] x = ... [Q] [Q] i
+    ... [Q] x = ... [Q]  Q
+    
+
+
+.. code:: ipython2
+
+    V('1 [2] [i 3] x')  # Kind of a pointless example.
+
+
+.. parsed-literal::
+
+                . 1 [2] [i 3] x
+              1 . [2] [i 3] x
+          1 [2] . [i 3] x
+    1 [2] [i 3] . x
+    1 [2] [i 3] . i 3
+          1 [2] . i 3 3
+              1 . 2 3 3
+            1 2 . 3 3
+          1 2 3 . 3
+        1 2 3 3 . 
+
+
+``void``
+========
+
+Implements `**Laws of Form**
+*arithmetic* <https://en.wikipedia.org/wiki/Laws_of_Form#The_primary_arithmetic_.28Chapter_4.29>`__
+over quote-only datastructures (that is, datastructures that consist
+soley of containers, without strings or numbers or anything else.)
+
+.. code:: ipython2
+
+    J('[] void')
+
+
+.. parsed-literal::
+
+    False
+
+
+.. code:: ipython2
+
+    J('[[]] void')
+
+
+.. parsed-literal::
+
+    True
+
+
+.. code:: ipython2
+
+    J('[[][[]]] void')
+
+
+.. parsed-literal::
+
+    True
+
+
+.. code:: ipython2
+
+    J('[[[]][[][]]] void')
+
+
+.. parsed-literal::
+
+    False
+
diff --git a/docs/3. Developing a Program.rst b/docs/3. Developing a Program.rst
new file mode 100644 (file)
index 0000000..29da686
--- /dev/null
@@ -0,0 +1,799 @@
+
+`Project Euler, first problem: "Multiples of 3 and 5" <https://projecteuler.net/problem=1>`__
+=============================================================================================
+
+::
+
+    If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
+
+    Find the sum of all the multiples of 3 or 5 below 1000.
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+Let's create a predicate that returns ``True`` if a number is a multiple
+of 3 or 5 and ``False`` otherwise.
+
+.. code:: ipython2
+
+    define('P == [3 % not] dupdip 5 % not or')
+
+.. code:: ipython2
+
+    V('80 P')
+
+
+.. parsed-literal::
+
+                 . 80 P
+              80 . P
+              80 . [3 % not] dupdip 5 % not or
+    80 [3 % not] . dupdip 5 % not or
+              80 . 3 % not 80 5 % not or
+            80 3 . % not 80 5 % not or
+               2 . not 80 5 % not or
+           False . 80 5 % not or
+        False 80 . 5 % not or
+      False 80 5 . % not or
+         False 0 . not or
+      False True . or
+            True . 
+
+
+Given the predicate function ``P`` a suitable program is:
+
+::
+
+    PE1 == 1000 range [P] filter sum
+
+This function generates a list of the integers from 0 to 999, filters
+that list by ``P``, and then sums the result.
+
+Logically this is fine, but pragmatically we are doing more work than we
+should be; we generate one thousand integers but actually use less than
+half of them. A better solution would be to generate just the multiples
+we want to sum, and to add them as we go rather than storing them and
+adding summing them at the end.
+
+At first I had the idea to use two counters and increase them by three
+and five, respectively. This way we only generate the terms that we
+actually want to sum. We have to proceed by incrementing the counter
+that is lower, or if they are equal, the three counter, and we have to
+take care not to double add numbers like 15 that are multiples of both
+three and five.
+
+This seemed a little clunky, so I tried a different approach.
+
+Consider the first few terms in the series:
+
+::
+
+    3 5 6 9 10 12 15 18 20 21 ...
+
+Subtract each number from the one after it (subtracting 0 from 3):
+
+::
+
+    3 5 6 9 10 12 15 18 20 21 24 25 27 30 ...
+    0 3 5 6  9 10 12 15 18 20 21 24 25 27 ...
+    -------------------------------------------
+    3 2 1 3  1  2  3  3  2  1  3  1  2  3 ...
+
+You get this lovely repeating palindromic sequence:
+
+::
+
+    3 2 1 3 1 2 3
+
+To make a counter that increments by factors of 3 and 5 you just add
+these differences to the counter one-by-one in a loop.
+
+To make use of this sequence to increment a counter and sum terms as we
+go we need a function that will accept the sum, the counter, and the
+next term to add, and that adds the term to the counter and a copy of
+the counter to the running sum. This function will do that:
+
+::
+
+    PE1.1 == + [+] dupdip
+
+.. code:: ipython2
+
+    define('PE1.1 == + [+] dupdip')
+
+.. code:: ipython2
+
+    V('0 0 3 PE1.1')
+
+
+.. parsed-literal::
+
+            . 0 0 3 PE1.1
+          0 . 0 3 PE1.1
+        0 0 . 3 PE1.1
+      0 0 3 . PE1.1
+      0 0 3 . + [+] dupdip
+        0 3 . [+] dupdip
+    0 3 [+] . dupdip
+        0 3 . + 3
+          3 . 3
+        3 3 . 
+
+
+.. code:: ipython2
+
+    V('0 0 [3 2 1 3 1 2 3] [PE1.1] step')
+
+
+.. parsed-literal::
+
+                                . 0 0 [3 2 1 3 1 2 3] [PE1.1] step
+                              0 . 0 [3 2 1 3 1 2 3] [PE1.1] step
+                            0 0 . [3 2 1 3 1 2 3] [PE1.1] step
+            0 0 [3 2 1 3 1 2 3] . [PE1.1] step
+    0 0 [3 2 1 3 1 2 3] [PE1.1] . step
+                  0 0 3 [PE1.1] . i [2 1 3 1 2 3] [PE1.1] step
+                          0 0 3 . PE1.1 [2 1 3 1 2 3] [PE1.1] step
+                          0 0 3 . + [+] dupdip [2 1 3 1 2 3] [PE1.1] step
+                            0 3 . [+] dupdip [2 1 3 1 2 3] [PE1.1] step
+                        0 3 [+] . dupdip [2 1 3 1 2 3] [PE1.1] step
+                            0 3 . + 3 [2 1 3 1 2 3] [PE1.1] step
+                              3 . 3 [2 1 3 1 2 3] [PE1.1] step
+                            3 3 . [2 1 3 1 2 3] [PE1.1] step
+              3 3 [2 1 3 1 2 3] . [PE1.1] step
+      3 3 [2 1 3 1 2 3] [PE1.1] . step
+                  3 3 2 [PE1.1] . i [1 3 1 2 3] [PE1.1] step
+                          3 3 2 . PE1.1 [1 3 1 2 3] [PE1.1] step
+                          3 3 2 . + [+] dupdip [1 3 1 2 3] [PE1.1] step
+                            3 5 . [+] dupdip [1 3 1 2 3] [PE1.1] step
+                        3 5 [+] . dupdip [1 3 1 2 3] [PE1.1] step
+                            3 5 . + 5 [1 3 1 2 3] [PE1.1] step
+                              8 . 5 [1 3 1 2 3] [PE1.1] step
+                            8 5 . [1 3 1 2 3] [PE1.1] step
+                8 5 [1 3 1 2 3] . [PE1.1] step
+        8 5 [1 3 1 2 3] [PE1.1] . step
+                  8 5 1 [PE1.1] . i [3 1 2 3] [PE1.1] step
+                          8 5 1 . PE1.1 [3 1 2 3] [PE1.1] step
+                          8 5 1 . + [+] dupdip [3 1 2 3] [PE1.1] step
+                            8 6 . [+] dupdip [3 1 2 3] [PE1.1] step
+                        8 6 [+] . dupdip [3 1 2 3] [PE1.1] step
+                            8 6 . + 6 [3 1 2 3] [PE1.1] step
+                             14 . 6 [3 1 2 3] [PE1.1] step
+                           14 6 . [3 1 2 3] [PE1.1] step
+                 14 6 [3 1 2 3] . [PE1.1] step
+         14 6 [3 1 2 3] [PE1.1] . step
+                 14 6 3 [PE1.1] . i [1 2 3] [PE1.1] step
+                         14 6 3 . PE1.1 [1 2 3] [PE1.1] step
+                         14 6 3 . + [+] dupdip [1 2 3] [PE1.1] step
+                           14 9 . [+] dupdip [1 2 3] [PE1.1] step
+                       14 9 [+] . dupdip [1 2 3] [PE1.1] step
+                           14 9 . + 9 [1 2 3] [PE1.1] step
+                             23 . 9 [1 2 3] [PE1.1] step
+                           23 9 . [1 2 3] [PE1.1] step
+                   23 9 [1 2 3] . [PE1.1] step
+           23 9 [1 2 3] [PE1.1] . step
+                 23 9 1 [PE1.1] . i [2 3] [PE1.1] step
+                         23 9 1 . PE1.1 [2 3] [PE1.1] step
+                         23 9 1 . + [+] dupdip [2 3] [PE1.1] step
+                          23 10 . [+] dupdip [2 3] [PE1.1] step
+                      23 10 [+] . dupdip [2 3] [PE1.1] step
+                          23 10 . + 10 [2 3] [PE1.1] step
+                             33 . 10 [2 3] [PE1.1] step
+                          33 10 . [2 3] [PE1.1] step
+                    33 10 [2 3] . [PE1.1] step
+            33 10 [2 3] [PE1.1] . step
+                33 10 2 [PE1.1] . i [3] [PE1.1] step
+                        33 10 2 . PE1.1 [3] [PE1.1] step
+                        33 10 2 . + [+] dupdip [3] [PE1.1] step
+                          33 12 . [+] dupdip [3] [PE1.1] step
+                      33 12 [+] . dupdip [3] [PE1.1] step
+                          33 12 . + 12 [3] [PE1.1] step
+                             45 . 12 [3] [PE1.1] step
+                          45 12 . [3] [PE1.1] step
+                      45 12 [3] . [PE1.1] step
+              45 12 [3] [PE1.1] . step
+                45 12 3 [PE1.1] . i
+                        45 12 3 . PE1.1
+                        45 12 3 . + [+] dupdip
+                          45 15 . [+] dupdip
+                      45 15 [+] . dupdip
+                          45 15 . + 15
+                             60 . 15
+                          60 15 . 
+
+
+So one ``step`` through all seven terms brings the counter to 15 and the
+total to 60.
+
+.. code:: ipython2
+
+    1000 / 15
+
+
+
+
+.. parsed-literal::
+
+    66
+
+
+
+.. code:: ipython2
+
+    66 * 15
+
+
+
+
+.. parsed-literal::
+
+    990
+
+
+
+.. code:: ipython2
+
+    1000 - 990
+
+
+
+
+.. parsed-literal::
+
+    10
+
+
+
+We only want the terms *less than* 1000.
+
+.. code:: ipython2
+
+    999 - 990
+
+
+
+
+.. parsed-literal::
+
+    9
+
+
+
+That means we want to run the full list of numbers sixty-six times to
+get to 990 and then the first four numbers 3 2 1 3 to get to 999.
+
+.. code:: ipython2
+
+    define('PE1 == 0 0 66 [[3 2 1 3 1 2 3] [PE1.1] step] times [3 2 1 3] [PE1.1] step pop')
+
+.. code:: ipython2
+
+    J('PE1')
+
+
+.. parsed-literal::
+
+    233168
+
+
+This form uses no extra storage and produces no unused summands. It's
+good but there's one more trick we can apply. The list of seven terms
+takes up at least seven bytes. But notice that all of the terms are less
+than four, and so each can fit in just two bits. We could store all
+seven terms in just fourteen bits and use masking and shifts to pick out
+each term as we go. This will use less space and save time loading whole
+integer terms from the list.
+
+::
+
+        3  2  1  3  1  2  3
+    0b 11 10 01 11 01 10 11 == 14811
+
+.. code:: ipython2
+
+    0b11100111011011
+
+
+
+
+.. parsed-literal::
+
+    14811
+
+
+
+.. code:: ipython2
+
+    define('PE1.2 == [3 & PE1.1] dupdip 2 >>')
+
+.. code:: ipython2
+
+    V('0 0 14811 PE1.2')
+
+
+.. parsed-literal::
+
+                          . 0 0 14811 PE1.2
+                        0 . 0 14811 PE1.2
+                      0 0 . 14811 PE1.2
+                0 0 14811 . PE1.2
+                0 0 14811 . [3 & PE1.1] dupdip 2 >>
+    0 0 14811 [3 & PE1.1] . dupdip 2 >>
+                0 0 14811 . 3 & PE1.1 14811 2 >>
+              0 0 14811 3 . & PE1.1 14811 2 >>
+                    0 0 3 . PE1.1 14811 2 >>
+                    0 0 3 . + [+] dupdip 14811 2 >>
+                      0 3 . [+] dupdip 14811 2 >>
+                  0 3 [+] . dupdip 14811 2 >>
+                      0 3 . + 3 14811 2 >>
+                        3 . 3 14811 2 >>
+                      3 3 . 14811 2 >>
+                3 3 14811 . 2 >>
+              3 3 14811 2 . >>
+                 3 3 3702 . 
+
+
+.. code:: ipython2
+
+    V('3 3 3702 PE1.2')
+
+
+.. parsed-literal::
+
+                         . 3 3 3702 PE1.2
+                       3 . 3 3702 PE1.2
+                     3 3 . 3702 PE1.2
+                3 3 3702 . PE1.2
+                3 3 3702 . [3 & PE1.1] dupdip 2 >>
+    3 3 3702 [3 & PE1.1] . dupdip 2 >>
+                3 3 3702 . 3 & PE1.1 3702 2 >>
+              3 3 3702 3 . & PE1.1 3702 2 >>
+                   3 3 2 . PE1.1 3702 2 >>
+                   3 3 2 . + [+] dupdip 3702 2 >>
+                     3 5 . [+] dupdip 3702 2 >>
+                 3 5 [+] . dupdip 3702 2 >>
+                     3 5 . + 5 3702 2 >>
+                       8 . 5 3702 2 >>
+                     8 5 . 3702 2 >>
+                8 5 3702 . 2 >>
+              8 5 3702 2 . >>
+                 8 5 925 . 
+
+
+.. code:: ipython2
+
+    V('0 0 14811 7 [PE1.2] times pop')
+
+
+.. parsed-literal::
+
+                          . 0 0 14811 7 [PE1.2] times pop
+                        0 . 0 14811 7 [PE1.2] times pop
+                      0 0 . 14811 7 [PE1.2] times pop
+                0 0 14811 . 7 [PE1.2] times pop
+              0 0 14811 7 . [PE1.2] times pop
+      0 0 14811 7 [PE1.2] . times pop
+        0 0 14811 [PE1.2] . i 6 [PE1.2] times pop
+                0 0 14811 . PE1.2 6 [PE1.2] times pop
+                0 0 14811 . [3 & PE1.1] dupdip 2 >> 6 [PE1.2] times pop
+    0 0 14811 [3 & PE1.1] . dupdip 2 >> 6 [PE1.2] times pop
+                0 0 14811 . 3 & PE1.1 14811 2 >> 6 [PE1.2] times pop
+              0 0 14811 3 . & PE1.1 14811 2 >> 6 [PE1.2] times pop
+                    0 0 3 . PE1.1 14811 2 >> 6 [PE1.2] times pop
+                    0 0 3 . + [+] dupdip 14811 2 >> 6 [PE1.2] times pop
+                      0 3 . [+] dupdip 14811 2 >> 6 [PE1.2] times pop
+                  0 3 [+] . dupdip 14811 2 >> 6 [PE1.2] times pop
+                      0 3 . + 3 14811 2 >> 6 [PE1.2] times pop
+                        3 . 3 14811 2 >> 6 [PE1.2] times pop
+                      3 3 . 14811 2 >> 6 [PE1.2] times pop
+                3 3 14811 . 2 >> 6 [PE1.2] times pop
+              3 3 14811 2 . >> 6 [PE1.2] times pop
+                 3 3 3702 . 6 [PE1.2] times pop
+               3 3 3702 6 . [PE1.2] times pop
+       3 3 3702 6 [PE1.2] . times pop
+         3 3 3702 [PE1.2] . i 5 [PE1.2] times pop
+                 3 3 3702 . PE1.2 5 [PE1.2] times pop
+                 3 3 3702 . [3 & PE1.1] dupdip 2 >> 5 [PE1.2] times pop
+     3 3 3702 [3 & PE1.1] . dupdip 2 >> 5 [PE1.2] times pop
+                 3 3 3702 . 3 & PE1.1 3702 2 >> 5 [PE1.2] times pop
+               3 3 3702 3 . & PE1.1 3702 2 >> 5 [PE1.2] times pop
+                    3 3 2 . PE1.1 3702 2 >> 5 [PE1.2] times pop
+                    3 3 2 . + [+] dupdip 3702 2 >> 5 [PE1.2] times pop
+                      3 5 . [+] dupdip 3702 2 >> 5 [PE1.2] times pop
+                  3 5 [+] . dupdip 3702 2 >> 5 [PE1.2] times pop
+                      3 5 . + 5 3702 2 >> 5 [PE1.2] times pop
+                        8 . 5 3702 2 >> 5 [PE1.2] times pop
+                      8 5 . 3702 2 >> 5 [PE1.2] times pop
+                 8 5 3702 . 2 >> 5 [PE1.2] times pop
+               8 5 3702 2 . >> 5 [PE1.2] times pop
+                  8 5 925 . 5 [PE1.2] times pop
+                8 5 925 5 . [PE1.2] times pop
+        8 5 925 5 [PE1.2] . times pop
+          8 5 925 [PE1.2] . i 4 [PE1.2] times pop
+                  8 5 925 . PE1.2 4 [PE1.2] times pop
+                  8 5 925 . [3 & PE1.1] dupdip 2 >> 4 [PE1.2] times pop
+      8 5 925 [3 & PE1.1] . dupdip 2 >> 4 [PE1.2] times pop
+                  8 5 925 . 3 & PE1.1 925 2 >> 4 [PE1.2] times pop
+                8 5 925 3 . & PE1.1 925 2 >> 4 [PE1.2] times pop
+                    8 5 1 . PE1.1 925 2 >> 4 [PE1.2] times pop
+                    8 5 1 . + [+] dupdip 925 2 >> 4 [PE1.2] times pop
+                      8 6 . [+] dupdip 925 2 >> 4 [PE1.2] times pop
+                  8 6 [+] . dupdip 925 2 >> 4 [PE1.2] times pop
+                      8 6 . + 6 925 2 >> 4 [PE1.2] times pop
+                       14 . 6 925 2 >> 4 [PE1.2] times pop
+                     14 6 . 925 2 >> 4 [PE1.2] times pop
+                 14 6 925 . 2 >> 4 [PE1.2] times pop
+               14 6 925 2 . >> 4 [PE1.2] times pop
+                 14 6 231 . 4 [PE1.2] times pop
+               14 6 231 4 . [PE1.2] times pop
+       14 6 231 4 [PE1.2] . times pop
+         14 6 231 [PE1.2] . i 3 [PE1.2] times pop
+                 14 6 231 . PE1.2 3 [PE1.2] times pop
+                 14 6 231 . [3 & PE1.1] dupdip 2 >> 3 [PE1.2] times pop
+     14 6 231 [3 & PE1.1] . dupdip 2 >> 3 [PE1.2] times pop
+                 14 6 231 . 3 & PE1.1 231 2 >> 3 [PE1.2] times pop
+               14 6 231 3 . & PE1.1 231 2 >> 3 [PE1.2] times pop
+                   14 6 3 . PE1.1 231 2 >> 3 [PE1.2] times pop
+                   14 6 3 . + [+] dupdip 231 2 >> 3 [PE1.2] times pop
+                     14 9 . [+] dupdip 231 2 >> 3 [PE1.2] times pop
+                 14 9 [+] . dupdip 231 2 >> 3 [PE1.2] times pop
+                     14 9 . + 9 231 2 >> 3 [PE1.2] times pop
+                       23 . 9 231 2 >> 3 [PE1.2] times pop
+                     23 9 . 231 2 >> 3 [PE1.2] times pop
+                 23 9 231 . 2 >> 3 [PE1.2] times pop
+               23 9 231 2 . >> 3 [PE1.2] times pop
+                  23 9 57 . 3 [PE1.2] times pop
+                23 9 57 3 . [PE1.2] times pop
+        23 9 57 3 [PE1.2] . times pop
+          23 9 57 [PE1.2] . i 2 [PE1.2] times pop
+                  23 9 57 . PE1.2 2 [PE1.2] times pop
+                  23 9 57 . [3 & PE1.1] dupdip 2 >> 2 [PE1.2] times pop
+      23 9 57 [3 & PE1.1] . dupdip 2 >> 2 [PE1.2] times pop
+                  23 9 57 . 3 & PE1.1 57 2 >> 2 [PE1.2] times pop
+                23 9 57 3 . & PE1.1 57 2 >> 2 [PE1.2] times pop
+                   23 9 1 . PE1.1 57 2 >> 2 [PE1.2] times pop
+                   23 9 1 . + [+] dupdip 57 2 >> 2 [PE1.2] times pop
+                    23 10 . [+] dupdip 57 2 >> 2 [PE1.2] times pop
+                23 10 [+] . dupdip 57 2 >> 2 [PE1.2] times pop
+                    23 10 . + 10 57 2 >> 2 [PE1.2] times pop
+                       33 . 10 57 2 >> 2 [PE1.2] times pop
+                    33 10 . 57 2 >> 2 [PE1.2] times pop
+                 33 10 57 . 2 >> 2 [PE1.2] times pop
+               33 10 57 2 . >> 2 [PE1.2] times pop
+                 33 10 14 . 2 [PE1.2] times pop
+               33 10 14 2 . [PE1.2] times pop
+       33 10 14 2 [PE1.2] . times pop
+         33 10 14 [PE1.2] . i 1 [PE1.2] times pop
+                 33 10 14 . PE1.2 1 [PE1.2] times pop
+                 33 10 14 . [3 & PE1.1] dupdip 2 >> 1 [PE1.2] times pop
+     33 10 14 [3 & PE1.1] . dupdip 2 >> 1 [PE1.2] times pop
+                 33 10 14 . 3 & PE1.1 14 2 >> 1 [PE1.2] times pop
+               33 10 14 3 . & PE1.1 14 2 >> 1 [PE1.2] times pop
+                  33 10 2 . PE1.1 14 2 >> 1 [PE1.2] times pop
+                  33 10 2 . + [+] dupdip 14 2 >> 1 [PE1.2] times pop
+                    33 12 . [+] dupdip 14 2 >> 1 [PE1.2] times pop
+                33 12 [+] . dupdip 14 2 >> 1 [PE1.2] times pop
+                    33 12 . + 12 14 2 >> 1 [PE1.2] times pop
+                       45 . 12 14 2 >> 1 [PE1.2] times pop
+                    45 12 . 14 2 >> 1 [PE1.2] times pop
+                 45 12 14 . 2 >> 1 [PE1.2] times pop
+               45 12 14 2 . >> 1 [PE1.2] times pop
+                  45 12 3 . 1 [PE1.2] times pop
+                45 12 3 1 . [PE1.2] times pop
+        45 12 3 1 [PE1.2] . times pop
+          45 12 3 [PE1.2] . i pop
+                  45 12 3 . PE1.2 pop
+                  45 12 3 . [3 & PE1.1] dupdip 2 >> pop
+      45 12 3 [3 & PE1.1] . dupdip 2 >> pop
+                  45 12 3 . 3 & PE1.1 3 2 >> pop
+                45 12 3 3 . & PE1.1 3 2 >> pop
+                  45 12 3 . PE1.1 3 2 >> pop
+                  45 12 3 . + [+] dupdip 3 2 >> pop
+                    45 15 . [+] dupdip 3 2 >> pop
+                45 15 [+] . dupdip 3 2 >> pop
+                    45 15 . + 15 3 2 >> pop
+                       60 . 15 3 2 >> pop
+                    60 15 . 3 2 >> pop
+                  60 15 3 . 2 >> pop
+                60 15 3 2 . >> pop
+                  60 15 0 . pop
+                    60 15 . 
+
+
+And so we have at last:
+
+.. code:: ipython2
+
+    define('PE1 == 0 0 66 [14811 7 [PE1.2] times pop] times 14811 4 [PE1.2] times popop')
+
+.. code:: ipython2
+
+    J('PE1')
+
+
+.. parsed-literal::
+
+    233168
+
+
+Let's refactor.
+
+::
+
+      14811 7 [PE1.2] times pop
+      14811 4 [PE1.2] times pop
+      14811 n [PE1.2] times pop
+    n 14811 swap [PE1.2] times pop
+
+.. code:: ipython2
+
+    define('PE1.3 == 14811 swap [PE1.2] times pop')
+
+Now we can simplify the definition above:
+
+.. code:: ipython2
+
+    define('PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop')
+
+.. code:: ipython2
+
+    J('PE1')
+
+
+.. parsed-literal::
+
+    233168
+
+
+Here's our joy program all in one place. It doesn't make so much sense,
+but if you have read through the above description of how it was derived
+I hope it's clear.
+
+::
+
+    PE1.1 == + [+] dupdip
+    PE1.2 == [3 & PE1.1] dupdip 2 >>
+    PE1.3 == 14811 swap [PE1.2] times pop
+    PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop
+
+Generator Version
+=================
+
+It's a little clunky iterating sixty-six times though the seven numbers
+then four more. In the *Generator Programs* notebook we derive a
+generator that can be repeatedly driven by the ``x`` combinator to
+produce a stream of the seven numbers repeating over and over again.
+
+.. code:: ipython2
+
+    define('PE1.terms == [0 swap [dup [pop 14811] [] branch [3 &] dupdip 2 >>] dip rest cons]')
+
+.. code:: ipython2
+
+    J('PE1.terms 21 [x] times')
+
+
+.. parsed-literal::
+
+    3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 [0 swap [dup [pop 14811] [] branch [3 &] dupdip 2 >>] dip rest cons]
+
+
+We know from above that we need sixty-six times seven then four more
+terms to reach up to but not over one thousand.
+
+.. code:: ipython2
+
+    J('7 66 * 4 +')
+
+
+.. parsed-literal::
+
+    466
+
+
+Here they are...
+~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('PE1.terms 466 [x] times pop')
+
+
+.. parsed-literal::
+
+    3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3
+
+
+...and they do sum to 999.
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('[PE1.terms 466 [x] times pop] run sum')
+
+
+.. parsed-literal::
+
+    999
+
+
+Now we can use ``PE1.1`` to accumulate the terms as we go, and then
+``pop`` the generator and the counter from the stack when we're done,
+leaving just the sum.
+
+.. code:: ipython2
+
+    J('0 0 PE1.terms 466 [x [PE1.1] dip] times popop')
+
+
+.. parsed-literal::
+
+    233168
+
+
+A little further analysis renders iteration unnecessary.
+========================================================
+
+Consider finding the sum of the positive integers less than or equal to
+ten.
+
+.. code:: ipython2
+
+    J('[10 9 8 7 6 5 4 3 2 1] sum')
+
+
+.. parsed-literal::
+
+    55
+
+
+Instead of summing them,
+`observe <https://en.wikipedia.org/wiki/File:Animated_proof_for_the_formula_giving_the_sum_of_the_first_integers_1%2B2%2B...%2Bn.gif>`__:
+
+::
+
+      10  9  8  7  6
+    +  1  2  3  4  5
+    ---- -- -- -- --
+      11 11 11 11 11
+      
+      11 * 5 = 55
+
+From the above example we can deduce that the sum of the first N
+positive integers is:
+
+::
+
+    (N + 1) * N / 2 
+
+(The formula also works for odd values of N, I'll leave that to you if
+you want to work it out or you can take my word for it.)
+
+.. code:: ipython2
+
+    define('F == dup ++ * 2 floordiv')
+
+.. code:: ipython2
+
+    V('10 F')
+
+
+.. parsed-literal::
+
+          . 10 F
+       10 . F
+       10 . dup ++ * 2 floordiv
+    10 10 . ++ * 2 floordiv
+    10 11 . * 2 floordiv
+      110 . 2 floordiv
+    110 2 . floordiv
+       55 . 
+
+
+Generalizing to Blocks of Terms
+-------------------------------
+
+We can apply the same reasoning to the PE1 problem.
+
+Between 0 and 990 inclusive there are sixty-six "blocks" of seven terms
+each, starting with:
+
+::
+
+    [3 5 6 9 10 12 15]
+
+And ending with:
+
+::
+
+    [978 980 981 984 985 987 990]
+
+If we reverse one of these two blocks and sum pairs...
+
+.. code:: ipython2
+
+    J('[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip')
+
+
+.. parsed-literal::
+
+    [[978 15] [980 12] [981 10] [984 9] [985 6] [987 5] [990 3]]
+
+
+.. code:: ipython2
+
+    J('[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map')
+
+
+.. parsed-literal::
+
+    [993 992 991 993 991 992 993]
+
+
+(Interesting that the sequence of seven numbers appears again in the
+rightmost digit of each term.)
+
+.. code:: ipython2
+
+    J('[ 3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map sum')
+
+
+.. parsed-literal::
+
+    6945
+
+
+Since there are sixty-six blocks and we are pairing them up, there must
+be thirty-three pairs, each of which sums to 6945. We also have these
+additional unpaired terms between 990 and 1000:
+
+::
+
+    993 995 996 999
+
+So we can give the "sum of all the multiples of 3 or 5 below 1000" like
+so:
+
+.. code:: ipython2
+
+    J('6945 33 * [993 995 996 999] cons sum')
+
+
+.. parsed-literal::
+
+    233168
+
+
+It's worth noting, I think, that this same reasoning holds for any two
+numbers :math:`n` and :math:`m` the multiples of which we hope to sum.
+The multiples would have a cycle of differences of length :math:`k` and
+so we could compute the sum of :math:`Nk` multiples as above.
+
+The sequence of differences will always be a palidrome. Consider an
+interval spanning the least common multiple of :math:`n` and :math:`m`:
+
+::
+
+    |   |   |   |   |   |   |   |
+    |      |      |      |      |
+
+Here we have 4 and 7, and you can read off the sequence of differences
+directly from the diagram: 4 3 1 4 2 2 4 1 3 4.
+
+Geometrically, the actual values of :math:`n` and :math:`m` and their
+*lcm* don't matter, the pattern they make will always be symmetrical
+around its midpoint. The same reasoning holds for multiples of more than
+two numbers.
+
+The Simplest Program
+====================
+
+Of course, the simplest joy program for the first Project Euler problem
+is just:
+
+::
+
+    PE1 == 233168
+
+Fin.
diff --git a/docs/4. Replacing Functions in the Dictionary.rst b/docs/4. Replacing Functions in the Dictionary.rst
new file mode 100644 (file)
index 0000000..f3d4dd0
--- /dev/null
@@ -0,0 +1,164 @@
+
+Preamble
+~~~~~~~~
+
+.. code:: ipython2
+
+    from notebook_preamble import D, J, V
+
+A long trace
+~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    V('[23 18] average')
+
+
+.. parsed-literal::
+
+                                      . [23 18] average
+                              [23 18] . average
+                              [23 18] . [sum 1.0 *] [size] cleave /
+                  [23 18] [sum 1.0 *] . [size] cleave /
+           [23 18] [sum 1.0 *] [size] . cleave /
+           [23 18] [sum 1.0 *] [size] . [i] app2 [popd] dip /
+       [23 18] [sum 1.0 *] [size] [i] . app2 [popd] dip /
+    [23 18] [[sum 1.0 *] [23 18]] [i] . infra first [[size] [23 18]] [i] infra first [popd] dip /
+                  [23 18] [sum 1.0 *] . i [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                              [23 18] . sum 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                                   41 . 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                               41 1.0 . * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                                 41.0 . [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                       41.0 [[23 18]] . swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                       [23 18] [41.0] . first [[size] [23 18]] [i] infra first [popd] dip /
+                         [23 18] 41.0 . [[size] [23 18]] [i] infra first [popd] dip /
+        [23 18] 41.0 [[size] [23 18]] . [i] infra first [popd] dip /
+    [23 18] 41.0 [[size] [23 18]] [i] . infra first [popd] dip /
+                       [23 18] [size] . i [41.0 [23 18]] swaack first [popd] dip /
+                              [23 18] . size [41.0 [23 18]] swaack first [popd] dip /
+                              [23 18] . 0 swap [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
+                            [23 18] 0 . swap [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
+                            0 [23 18] . [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
+                   0 [23 18] [pop ++] . step [41.0 [23 18]] swaack first [popd] dip /
+                        0 23 [pop ++] . i [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
+                                 0 23 . pop ++ [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
+                                    0 . ++ [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
+                                    1 . [18] [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
+                               1 [18] . [pop ++] step [41.0 [23 18]] swaack first [popd] dip /
+                      1 [18] [pop ++] . step [41.0 [23 18]] swaack first [popd] dip /
+                        1 18 [pop ++] . i [41.0 [23 18]] swaack first [popd] dip /
+                                 1 18 . pop ++ [41.0 [23 18]] swaack first [popd] dip /
+                                    1 . ++ [41.0 [23 18]] swaack first [popd] dip /
+                                    2 . [41.0 [23 18]] swaack first [popd] dip /
+                     2 [41.0 [23 18]] . swaack first [popd] dip /
+                     [23 18] 41.0 [2] . first [popd] dip /
+                       [23 18] 41.0 2 . [popd] dip /
+                [23 18] 41.0 2 [popd] . dip /
+                         [23 18] 41.0 . popd 2 /
+                                 41.0 . 2 /
+                               41.0 2 . /
+                                 20.5 . 
+
+
+Replacing ``sum`` and ``size`` with "compiled" versions.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Both ``sum`` and ``size`` are
+`catamorphisms <https://en.wikipedia.org/wiki/Catamorphism>`__, they
+each convert a sequence to a single value.
+
+.. code:: ipython2
+
+    J('[sum] help')
+
+
+.. parsed-literal::
+
+    Given a quoted sequence of numbers return the sum.
+    
+    sum == 0 swap [+] step
+    
+
+
+.. code:: ipython2
+
+    J('[size] help')
+
+
+.. parsed-literal::
+
+    0 swap [pop ++] step
+    
+
+
+We can use "compiled" versions (they're not really compiled in this
+case, they're hand-written in Python) to speed up evaluation and make
+the trace more readable. The ``sum`` function is already in the library.
+It gets shadowed by the definition version above during
+``initialize()``.
+
+.. code:: ipython2
+
+    from joy.library import SimpleFunctionWrapper, primitives
+    from joy.utils.stack import iter_stack
+    
+    
+    @SimpleFunctionWrapper
+    def size(stack):
+        '''Return the size of the sequence on the stack.'''
+        sequence, stack = stack
+        n = 0
+        for _ in iter_stack(sequence):
+            n += 1
+        return n, stack
+    
+    
+    sum_ = next(p for p in primitives if p.name == 'sum')
+
+Now we replace them old versions in the dictionary with the new versions
+and re-evaluate the expression.
+
+.. code:: ipython2
+
+    old_sum, D['sum'] = D['sum'], sum_
+    old_size, D['size'] = D['size'], size
+
+You can see that ``size`` and ``sum`` now execute in a single step.
+
+.. code:: ipython2
+
+    V('[23 18] average')
+
+
+.. parsed-literal::
+
+                                      . [23 18] average
+                              [23 18] . average
+                              [23 18] . [sum 1.0 *] [size] cleave /
+                  [23 18] [sum 1.0 *] . [size] cleave /
+           [23 18] [sum 1.0 *] [size] . cleave /
+           [23 18] [sum 1.0 *] [size] . [i] app2 [popd] dip /
+       [23 18] [sum 1.0 *] [size] [i] . app2 [popd] dip /
+    [23 18] [[sum 1.0 *] [23 18]] [i] . infra first [[size] [23 18]] [i] infra first [popd] dip /
+                  [23 18] [sum 1.0 *] . i [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                              [23 18] . sum 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                                   41 . 1.0 * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                               41 1.0 . * [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                                 41.0 . [[23 18]] swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                       41.0 [[23 18]] . swaack first [[size] [23 18]] [i] infra first [popd] dip /
+                       [23 18] [41.0] . first [[size] [23 18]] [i] infra first [popd] dip /
+                         [23 18] 41.0 . [[size] [23 18]] [i] infra first [popd] dip /
+        [23 18] 41.0 [[size] [23 18]] . [i] infra first [popd] dip /
+    [23 18] 41.0 [[size] [23 18]] [i] . infra first [popd] dip /
+                       [23 18] [size] . i [41.0 [23 18]] swaack first [popd] dip /
+                              [23 18] . size [41.0 [23 18]] swaack first [popd] dip /
+                                    2 . [41.0 [23 18]] swaack first [popd] dip /
+                     2 [41.0 [23 18]] . swaack first [popd] dip /
+                     [23 18] 41.0 [2] . first [popd] dip /
+                       [23 18] 41.0 2 . [popd] dip /
+                [23 18] 41.0 2 [popd] . dip /
+                         [23 18] 41.0 . popd 2 /
+                                 41.0 . 2 /
+                               41.0 2 . /
+                                 20.5 . 
+
diff --git a/docs/Advent of Code 2017 December 1st.rst b/docs/Advent of Code 2017 December 1st.rst
new file mode 100644 (file)
index 0000000..d5bb543
--- /dev/null
@@ -0,0 +1,288 @@
+
+Advent of Code 2017
+===================
+
+December 1st
+------------
+
+[Given] a sequence of digits (your puzzle input) and find the sum of all
+digits that match the next digit in the list. The list is circular, so
+the digit after the last digit is the first digit in the list.
+
+For example:
+
+-  1122 produces a sum of 3 (1 + 2) because the first digit (1) matches
+   the second digit and the third digit (2) matches the fourth digit.
+-  1111 produces 4 because each digit (all 1) matches the next.
+-  1234 produces 0 because no digit matches the next.
+-  91212129 produces 9 because the only digit that matches the next one
+   is the last digit, 9.
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+I'll assume the input is a Joy sequence of integers (as opposed to a
+string or something else.)
+
+We might proceed by creating a word that makes a copy of the sequence
+with the first item moved to the last, and zips it with the original to
+make a list of pairs, and a another word that adds (one of) each pair to
+a total if the pair matches.
+
+::
+
+    AoC2017.1 == pair_up total_matches
+
+Let's derive ``pair_up``:
+
+::
+
+         [a b c] pair_up
+    -------------------------
+       [[a b] [b c] [c a]]
+
+Straightforward (although the order of each pair is reversed, due to the
+way ``zip`` works, but it doesn't matter for this program):
+
+::
+
+    [a b c] dup
+    [a b c] [a b c] uncons swap
+    [a b c] [b c] a unit concat
+    [a b c] [b c a] zip
+    [[b a] [c b] [a c]]
+
+.. code:: ipython2
+
+    define('pair_up == dup uncons swap unit concat zip')
+
+.. code:: ipython2
+
+    J('[1 2 3] pair_up')
+
+
+.. parsed-literal::
+
+    [[2 1] [3 2] [1 3]]
+
+
+.. code:: ipython2
+
+    J('[1 2 2 3] pair_up')
+
+
+.. parsed-literal::
+
+    [[2 1] [2 2] [3 2] [1 3]]
+
+
+Now we need to derive ``total_matches``. It will be a ``step`` function:
+
+::
+
+    total_matches == 0 swap [F] step
+
+Where ``F`` will have the pair to work with, and it will basically be a
+``branch`` or ``ifte``.
+
+::
+
+    total [n m] F
+
+It will probably be easier to write if we dequote the pair:
+
+::
+
+       total [n m] i F′
+    ----------------------
+         total n m F′
+
+Now ``F′`` becomes just:
+
+::
+
+    total n m [=] [pop +] [popop] ifte
+
+So:
+
+::
+
+    F == i [=] [pop +] [popop] ifte
+
+And thus:
+
+::
+
+    total_matches == 0 swap [i [=] [pop +] [popop] ifte] step
+
+.. code:: ipython2
+
+    define('total_matches == 0 swap [i [=] [pop +] [popop] ifte] step')
+
+.. code:: ipython2
+
+    J('[1 2 3] pair_up total_matches')
+
+
+.. parsed-literal::
+
+    0
+
+
+.. code:: ipython2
+
+    J('[1 2 2 3] pair_up total_matches')
+
+
+.. parsed-literal::
+
+    2
+
+
+Now we can define our main program and evaluate it on the examples.
+
+.. code:: ipython2
+
+    define('AoC2017.1 == pair_up total_matches')
+
+.. code:: ipython2
+
+    J('[1 1 2 2] AoC2017.1')
+
+
+.. parsed-literal::
+
+    3
+
+
+.. code:: ipython2
+
+    J('[1 1 1 1] AoC2017.1')
+
+
+.. parsed-literal::
+
+    4
+
+
+.. code:: ipython2
+
+    J('[1 2 3 4] AoC2017.1')
+
+
+.. parsed-literal::
+
+    0
+
+
+.. code:: ipython2
+
+    J('[9 1 2 1 2 1 2 9] AoC2017.1')
+
+
+.. parsed-literal::
+
+    9
+
+
+.. code:: ipython2
+
+    J('[9 1 2 1 2 1 2 9] AoC2017.1')
+
+
+.. parsed-literal::
+
+    9
+
+
+::
+
+          pair_up == dup uncons swap unit concat zip
+    total_matches == 0 swap [i [=] [pop +] [popop] ifte] step
+
+        AoC2017.1 == pair_up total_matches
+
+Now the paired digit is "halfway" round.
+
+::
+
+    [a b c d] dup size 2 / [drop] [take reverse] cleave concat zip
+
+.. code:: ipython2
+
+    J('[1 2 3 4] dup size 2 / [drop] [take reverse] cleave concat zip')
+
+
+.. parsed-literal::
+
+    [[3 1] [4 2] [1 3] [2 4]]
+
+
+I realized that each pair is repeated...
+
+.. code:: ipython2
+
+    J('[1 2 3 4] dup size 2 / [drop] [take reverse] cleave  zip')
+
+
+.. parsed-literal::
+
+    [1 2 3 4] [[1 3] [2 4]]
+
+
+.. code:: ipython2
+
+    define('AoC2017.1.extra == dup size 2 / [drop] [take reverse] cleave  zip swap pop total_matches 2 *')
+
+.. code:: ipython2
+
+    J('[1 2 1 2] AoC2017.1.extra')
+
+
+.. parsed-literal::
+
+    6
+
+
+.. code:: ipython2
+
+    J('[1 2 2 1] AoC2017.1.extra')
+
+
+.. parsed-literal::
+
+    0
+
+
+.. code:: ipython2
+
+    J('[1 2 3 4 2 5] AoC2017.1.extra')
+
+
+.. parsed-literal::
+
+    4
+
+
+Refactor FTW
+============
+
+With Joy a great deal of the heuristics from Forth programming carry
+over nicely. For example, refactoring into small, well-scoped commands
+with mnemonic names...
+
+::
+
+             rotate_seq == uncons swap unit concat
+                pair_up == dup rotate_seq zip
+           add_if_match == [=] [pop +] [popop] ifte
+          total_matches == [i add_if_match] step_zero
+
+              AoC2017.1 == pair_up total_matches
+
+           half_of_size == dup size 2 /
+               split_at == [drop] [take reverse] cleave
+          pair_up.extra == half_of_size split_at zip swap pop
+
+        AoC2017.1.extra == pair_up.extra total_matches 2 *
diff --git a/docs/Advent of Code 2017 December 2nd.rst b/docs/Advent of Code 2017 December 2nd.rst
new file mode 100644 (file)
index 0000000..7b85b26
--- /dev/null
@@ -0,0 +1,432 @@
+
+Advent of Code 2017
+===================
+
+December 2nd
+------------
+
+For each row, determine the difference between the largest value and the
+smallest value; the checksum is the sum of all of these differences.
+
+For example, given the following spreadsheet:
+
+::
+
+    5 1 9 5
+    7 5 3
+    2 4 6 8
+
+-  The first row's largest and smallest values are 9 and 1, and their
+   difference is 8.
+-  The second row's largest and smallest values are 7 and 3, and their
+   difference is 4.
+-  The third row's difference is 6.
+
+In this example, the spreadsheet's checksum would be 8 + 4 + 6 = 18.
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+I'll assume the input is a Joy sequence of sequences of integers.
+
+::
+
+    [[5 1 9 5]
+     [7 5 3]
+     [2 4 6 8]]
+
+So, obviously, the initial form will be a ``step`` function:
+
+::
+
+    AoC2017.2 == 0 swap [F +] step
+
+This function ``F`` must get the ``max`` and ``min`` of a row of numbers
+and subtract. We can define a helper function ``maxmin`` which does
+this:
+
+.. code:: ipython2
+
+    define('maxmin == [max] [min] cleave')
+
+.. code:: ipython2
+
+    J('[1 2 3] maxmin')
+
+
+.. parsed-literal::
+
+    3 1
+
+
+Then ``F`` just does that then subtracts the min from the max:
+
+::
+
+    F == maxmin -
+
+So:
+
+.. code:: ipython2
+
+    define('AoC2017.2 == [maxmin - +] step_zero')
+
+.. code:: ipython2
+
+    J('''
+    
+    [[5 1 9 5]
+     [7 5 3]
+     [2 4 6 8]] AoC2017.2
+    
+    ''')
+
+
+.. parsed-literal::
+
+    18
+
+
+...find the only two numbers in each row where one evenly divides the
+other - that is, where the result of the division operation is a whole
+number. They would like you to find those numbers on each line, divide
+them, and add up each line's result.
+
+For example, given the following spreadsheet:
+
+::
+
+    5 9 2 8
+    9 4 7 3
+    3 8 6 5
+
+-  In the first row, the only two numbers that evenly divide are 8 and
+   2; the result of this division is 4.
+-  In the second row, the two numbers are 9 and 3; the result is 3.
+-  In the third row, the result is 2.
+
+In this example, the sum of the results would be 4 + 3 + 2 = 9.
+
+What is the sum of each row's result in your puzzle input?
+
+.. code:: ipython2
+
+    J('[5 9 2 8] sort reverse')
+
+
+.. parsed-literal::
+
+    [9 8 5 2]
+
+
+.. code:: ipython2
+
+    J('[9 8 5 2] uncons [swap [divmod] cons] dupdip')
+
+
+.. parsed-literal::
+
+    [8 5 2] [9 divmod] [8 5 2]
+
+
+::
+
+    [9 8 5 2] uncons [swap [divmod] cons F] dupdip G
+      [8 5 2]            [9 divmod]      F [8 5 2] G
+
+.. code:: ipython2
+
+    V('[8 5 2] [9 divmod] [uncons swap] dip dup [i not] dip')
+
+
+.. parsed-literal::
+
+                                          . [8 5 2] [9 divmod] [uncons swap] dip dup [i not] dip
+                                  [8 5 2] . [9 divmod] [uncons swap] dip dup [i not] dip
+                       [8 5 2] [9 divmod] . [uncons swap] dip dup [i not] dip
+         [8 5 2] [9 divmod] [uncons swap] . dip dup [i not] dip
+                                  [8 5 2] . uncons swap [9 divmod] dup [i not] dip
+                                  8 [5 2] . swap [9 divmod] dup [i not] dip
+                                  [5 2] 8 . [9 divmod] dup [i not] dip
+                       [5 2] 8 [9 divmod] . dup [i not] dip
+            [5 2] 8 [9 divmod] [9 divmod] . [i not] dip
+    [5 2] 8 [9 divmod] [9 divmod] [i not] . dip
+                       [5 2] 8 [9 divmod] . i not [9 divmod]
+                                  [5 2] 8 . 9 divmod not [9 divmod]
+                                [5 2] 8 9 . divmod not [9 divmod]
+                                [5 2] 1 1 . not [9 divmod]
+                            [5 2] 1 False . [9 divmod]
+                 [5 2] 1 False [9 divmod] . 
+
+
+Tricky
+------
+
+Let's think.
+
+Given a *sorted* sequence (from highest to lowest) we want to \* for
+head, tail in sequence \* for term in tail: \* check if the head % term
+== 0 \* if so compute head / term and terminate loop \* else continue
+
+So we want a ``loop`` I think
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    [a b c d] True [Q] loop
+    [a b c d] Q    [Q] loop
+
+``Q`` should either leave the result and False, or the ``rest`` and
+True.
+
+::
+
+       [a b c d] Q
+    -----------------
+        result 0
+
+       [a b c d] Q
+    -----------------
+        [b c d] 1
+
+This suggests that ``Q`` should start with:
+
+::
+
+    [a b c d] uncons dup roll<
+    [b c d] [b c d] a
+
+Now we just have to ``pop`` it if we don't need it.
+
+::
+
+    [b c d] [b c d] a [P] [T] [cons] app2 popdd [E] primrec
+    [b c d] [b c d] [a P] [a T]                 [E] primrec
+
+--------------
+
+::
+
+    w/ Q == [% not] [T] [F] primrec
+
+            [a b c d] uncons
+            a [b c d] tuck
+    [b c d] a [b c d] uncons
+    [b c d] a b [c d] roll>
+    [b c d] [c d] a b Q
+    [b c d] [c d] a b [% not] [T] [F] primrec
+
+    [b c d] [c d] a b T
+    [b c d] [c d] a b / roll> popop 0
+
+    [b c d] [c d] a b F                   Q
+    [b c d] [c d] a b pop swap uncons ... Q
+    [b c d] [c d] a       swap uncons ... Q
+    [b c d] a [c d]            uncons ... Q
+    [b c d] a c [d]                   roll> Q
+    [b c d] [d] a c Q
+
+    Q == [% not] [/ roll> popop 0] [pop swap uncons roll>] primrec
+
+    uncons tuck uncons roll> Q
+
+.. code:: ipython2
+
+    J('[8 5 3 2] 9 [swap] [% not] [cons] app2 popdd')
+
+
+.. parsed-literal::
+
+    [8 5 3 2] [9 swap] [9 % not]
+
+
+--------------
+
+::
+
+            [a b c d] uncons
+            a [b c d] tuck
+    [b c d] a [b c d] [not] [popop 1] [Q] ifte
+
+    [b c d] a [] popop 1
+    [b c d] 1
+
+    [b c d] a [b c d] Q 
+
+
+       a [...] Q
+    ---------------
+       result 0
+
+       a [...] Q
+    ---------------
+           1
+
+
+    w/ Q == [first % not] [first / 0] [rest [not] [popop 1]] [ifte]
+
+
+
+    a [b c d] [first % not] [first / 0] [rest [not] [popop 1]] [ifte]
+    a [b c d]  first % not
+    a b % not
+    a%b not
+    bool(a%b)
+
+    a [b c d] [first % not] [first / 0] [rest [not] [popop 1]] [ifte]
+    a [b c d]                first / 0
+    a b / 0
+    a/b 0
+
+    a [b c d] [first % not] [first / 0] [rest [not] [popop 1]]   [ifte]
+    a [b c d]                            rest [not] [popop 1] [Q] ifte
+    a [c d]                                   [not] [popop 1] [Q] ifte
+    a [c d]                                   [not] [popop 1] [Q] ifte
+
+    a [c d] [not] [popop 1] [Q] ifte
+    a [c d]  not
+
+    a [] popop 1
+    1
+
+    a [c d] Q
+
+
+    uncons tuck [first % not] [first / 0] [rest [not] [popop 1]] [ifte]
+
+I finally sat down with a piece of paper and blocked it out.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+First, I made a function ``G`` that expects a number and a sequence of
+candidates and return the result or zero:
+
+::
+
+       n [...] G
+    ---------------
+        result
+
+       n [...] G
+    ---------------
+           0
+
+It's a recursive function that conditionally executes the recursive part
+of its recursive branch
+
+::
+
+    [Pg] [E] [R1 [Pi] [T]] [ifte] genrec
+
+The recursive branch is the else-part of the inner ``ifte``:
+
+::
+
+    G == [Pg] [E] [R1 [Pi] [T]]   [ifte] genrec
+      == [Pg] [E] [R1 [Pi] [T] [G] ifte] ifte
+
+But this is in hindsight. Going forward I derived:
+
+::
+
+    G == [first % not]
+         [first /]
+         [rest [not] [popop 0]]
+         [ifte] genrec
+
+The predicate detects if the ``n`` can be evenly divided by the
+``first`` item in the list. If so, the then-part returns the result.
+Otherwise, we have:
+
+::
+
+    n [m ...] rest [not] [popop 0] [G] ifte
+    n [...]        [not] [popop 0] [G] ifte
+
+This ``ifte`` guards against empty sequences and returns zero in that
+case, otherwise it executes ``G``.
+
+.. code:: ipython2
+
+    define('G == [first % not] [first /] [rest [not] [popop 0]] [ifte] genrec')
+
+Now we need a word that uses ``G`` on each (head, tail) pair of a
+sequence until it finds a (non-zero) result. It's going to be designed
+to work on a stack that has some candidate ``n``, a sequence of possible
+divisors, and a result that is zero to signal to continue (a non-zero
+value implies that it is the discovered result):
+
+::
+
+       n [...] p find-result
+    ---------------------------
+              result
+
+It applies ``G`` using ``nullary`` because if it fails with one
+candidate it needs the list to get the next one (the list is otherwise
+consumed by ``G``.)
+
+::
+
+    find-result == [0 >] [roll> popop] [roll< popop uncons [G] nullary] primrec
+
+    n [...] p [0 >] [roll> popop] [roll< popop uncons [G] nullary] primrec
+
+The base-case is trivial, return the (non-zero) result. The recursive
+branch...
+
+::
+
+    n [...] p roll< popop uncons [G] nullary find-result
+    [...] p n       popop uncons [G] nullary find-result
+    [...]                 uncons [G] nullary find-result
+    m [..]                       [G] nullary find-result
+    m [..] p                                 find-result
+
+The puzzle states that the input is well-formed, meaning that we can
+expect a result before the row sequence empties and so do not need to
+guard the ``uncons``.
+
+.. code:: ipython2
+
+    define('find-result == [0 >] [roll> popop] [roll< popop uncons [G] nullary] primrec')
+
+.. code:: ipython2
+
+    J('[11 9 8 7 3 2] 0 tuck find-result')
+
+
+.. parsed-literal::
+
+    3.0
+
+
+In order to get the thing started, we need to ``sort`` the list in
+descending order, then prime the ``find-result`` function with a dummy
+candidate value and zero ("continue") flag.
+
+.. code:: ipython2
+
+    define('prep-row == sort reverse 0 tuck')
+
+Now we can define our program.
+
+.. code:: ipython2
+
+    define('AoC20017.2.extra == [prep-row find-result +] step_zero')
+
+.. code:: ipython2
+
+    J('''
+    
+    [[5 9 2 8]
+     [9 4 7 3]
+     [3 8 6 5]] AoC20017.2.extra
+    
+    ''')
+
+
+.. parsed-literal::
+
+    9.0
+
diff --git a/docs/Advent of Code 2017 December 3rd.rst b/docs/Advent of Code 2017 December 3rd.rst
new file mode 100644 (file)
index 0000000..2283c7f
--- /dev/null
@@ -0,0 +1,973 @@
+
+Advent of Code 2017
+===================
+
+December 3rd
+------------
+
+You come across an experimental new kind of memory stored on an infinite
+two-dimensional grid.
+
+Each square on the grid is allocated in a spiral pattern starting at a
+location marked 1 and then counting up while spiraling outward. For
+example, the first few squares are allocated like this:
+
+::
+
+    17  16  15  14  13
+    18   5   4   3  12
+    19   6   1   2  11
+    20   7   8   9  10
+    21  22  23---> ...
+
+While this is very space-efficient (no squares are skipped), requested
+data must be carried back to square 1 (the location of the only access
+port for this memory system) by programs that can only move up, down,
+left, or right. They always take the shortest path: the Manhattan
+Distance between the location of the data and square 1.
+
+For example:
+
+-  Data from square 1 is carried 0 steps, since it's at the access port.
+-  Data from square 12 is carried 3 steps, such as: down, left, left.
+-  Data from square 23 is carried only 2 steps: up twice.
+-  Data from square 1024 must be carried 31 steps.
+
+How many steps are required to carry the data from the square identified
+in your puzzle input all the way to the access port?
+
+Analysis
+~~~~~~~~
+
+I freely admit that I worked out the program I wanted to write using
+graph paper and some Python doodles. There's no point in trying to write
+a Joy program until I'm sure I understand the problem well enough.
+
+The first thing I did was to write a column of numbers from 1 to n (32
+as it happens) and next to them the desired output number, to look for
+patterns directly:
+
+::
+
+    1  0
+    2  1
+    3  2
+    4  1
+    5  2
+    6  1
+    7  2
+    8  1
+    9  2
+    10 3
+    11 2
+    12 3
+    13 4
+    14 3
+    15 2
+    16 3
+    17 4
+    18 3
+    19 2
+    20 3
+    21 4
+    22 3
+    23 2
+    24 3
+    25 4
+    26 5
+    27 4
+    28 3
+    29 4
+    30 5
+    31 6
+    32 5
+
+There are four groups repeating for a given "rank", then the pattern
+enlarges and four groups repeat again, etc.
+
+::
+
+            1 2
+          3 2 3 4
+        5 4 3 4 5 6
+      7 6 5 4 5 6 7 8
+    9 8 7 6 5 6 7 8 9 10
+
+Four of this pyramid interlock to tile the plane extending from the
+initial "1" square.
+
+::
+
+             2   3   |    4  5   |    6  7   |    8  9
+          10 11 12 13|14 15 16 17|18 19 20 21|22 23 24 25
+
+And so on.
+
+We can figure out the pattern for a row of the pyramid at a given "rank"
+:math:`k`:
+
+:math:`2k - 1, 2k - 2, ..., k, k + 1, k + 2, ..., 2k`
+
+or
+
+:math:`k + (k - 1), k + (k - 2), ..., k, k + 1, k + 2, ..., k + k`
+
+This shows that the series consists at each place of :math:`k` plus some
+number that begins at :math:`k - 1`, decreases to zero, then increases
+to :math:`k`. Each row has :math:`2k` members.
+
+Let's figure out how, given an index into a row, we can calculate the
+value there. The index will be from 0 to :math:`k - 1`.
+
+Let's look at an example, with :math:`k = 4`:
+
+::
+
+    0 1 2 3 4 5 6 7
+    7 6 5 4 5 6 7 8
+
+.. code:: ipython2
+
+    k = 4
+
+Subtract :math:`k` from the index and take the absolute value:
+
+.. code:: ipython2
+
+    for n in range(2 * k):
+        print abs(n - k),
+
+
+.. parsed-literal::
+
+    4 3 2 1 0 1 2 3
+
+
+Not quite. Subtract :math:`k - 1` from the index and take the absolute
+value:
+
+.. code:: ipython2
+
+    for n in range(2 * k):
+        print abs(n - (k - 1)),
+
+
+.. parsed-literal::
+
+    3 2 1 0 1 2 3 4
+
+
+Great, now add :math:`k`...
+
+.. code:: ipython2
+
+    for n in range(2 * k):
+        print abs(n - (k - 1)) + k,
+
+
+.. parsed-literal::
+
+    7 6 5 4 5 6 7 8
+
+
+So to write a function that can give us the value of a row at a given
+index:
+
+.. code:: ipython2
+
+    def row_value(k, i):
+        i %= (2 * k)  # wrap the index at the row boundary.
+        return abs(i - (k - 1)) + k
+
+.. code:: ipython2
+
+    k = 5
+    for i in range(2 * k):
+        print row_value(k, i),
+
+
+.. parsed-literal::
+
+    9 8 7 6 5 6 7 8 9 10
+
+
+(I'm leaving out details of how I figured this all out and just giving
+the relevent bits. It took a little while to zero in of the aspects of
+the pattern that were important for the task.)
+
+Finding the rank and offset of a number.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now that we can compute the desired output value for a given rank and
+the offset (index) into that rank, we need to determine how to find the
+rank and offset of a number.
+
+The rank is easy to find by iteratively stripping off the amount already
+covered by previous ranks until you find the one that brackets the
+target number. Because each row is :math:`2k` places and there are
+:math:`4` per rank each rank contains :math:`8k` places. Counting the
+initial square we have:
+
+:math:`corner_k = 1 + \sum_{n=1}^k 8n`
+
+I'm not mathematically sophisticated enough to turn this directly into a
+formula (but Sympy is, see below.) I'm going to write a simple Python
+function to iterate and search:
+
+.. code:: ipython2
+
+    def rank_and_offset(n):
+        assert n >= 2  # Guard the domain.
+        n -= 2  # Subtract two,
+                # one for the initial square,
+                # and one because we are counting from 1 instead of 0.
+        k = 1
+        while True:
+            m = 8 * k  # The number of places total in this rank, 4(2k).
+            if n < m:
+                return k, n % (2 * k)
+            n -= m  # Remove this rank's worth.
+            k += 1
+
+.. code:: ipython2
+
+    for n in range(2, 51):
+        print n, rank_and_offset(n)
+
+
+.. parsed-literal::
+
+    2 (1, 0)
+    3 (1, 1)
+    4 (1, 0)
+    5 (1, 1)
+    6 (1, 0)
+    7 (1, 1)
+    8 (1, 0)
+    9 (1, 1)
+    10 (2, 0)
+    11 (2, 1)
+    12 (2, 2)
+    13 (2, 3)
+    14 (2, 0)
+    15 (2, 1)
+    16 (2, 2)
+    17 (2, 3)
+    18 (2, 0)
+    19 (2, 1)
+    20 (2, 2)
+    21 (2, 3)
+    22 (2, 0)
+    23 (2, 1)
+    24 (2, 2)
+    25 (2, 3)
+    26 (3, 0)
+    27 (3, 1)
+    28 (3, 2)
+    29 (3, 3)
+    30 (3, 4)
+    31 (3, 5)
+    32 (3, 0)
+    33 (3, 1)
+    34 (3, 2)
+    35 (3, 3)
+    36 (3, 4)
+    37 (3, 5)
+    38 (3, 0)
+    39 (3, 1)
+    40 (3, 2)
+    41 (3, 3)
+    42 (3, 4)
+    43 (3, 5)
+    44 (3, 0)
+    45 (3, 1)
+    46 (3, 2)
+    47 (3, 3)
+    48 (3, 4)
+    49 (3, 5)
+    50 (4, 0)
+
+
+.. code:: ipython2
+
+    for n in range(2, 51):
+        k, i = rank_and_offset(n)
+        print n, row_value(k, i)
+
+
+.. parsed-literal::
+
+    2 1
+    3 2
+    4 1
+    5 2
+    6 1
+    7 2
+    8 1
+    9 2
+    10 3
+    11 2
+    12 3
+    13 4
+    14 3
+    15 2
+    16 3
+    17 4
+    18 3
+    19 2
+    20 3
+    21 4
+    22 3
+    23 2
+    24 3
+    25 4
+    26 5
+    27 4
+    28 3
+    29 4
+    30 5
+    31 6
+    32 5
+    33 4
+    34 3
+    35 4
+    36 5
+    37 6
+    38 5
+    39 4
+    40 3
+    41 4
+    42 5
+    43 6
+    44 5
+    45 4
+    46 3
+    47 4
+    48 5
+    49 6
+    50 7
+
+
+Putting it all together
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    def row_value(k, i):
+        return abs(i - (k - 1)) + k
+    
+    
+    def rank_and_offset(n):
+        n -= 2  # Subtract two,
+                # one for the initial square,
+                # and one because we are counting from 1 instead of 0.
+        k = 1
+        while True:
+            m = 8 * k  # The number of places total in this rank, 4(2k).
+            if n < m:
+                return k, n % (2 * k)
+            n -= m  # Remove this rank's worth.
+            k += 1
+    
+    
+    def aoc20173(n):
+        if n <= 1:
+            return 0
+        k, i = rank_and_offset(n)
+        return row_value(k, i)
+
+.. code:: ipython2
+
+    aoc20173(23)
+
+
+
+
+.. parsed-literal::
+
+    2
+
+
+
+.. code:: ipython2
+
+    aoc20173(23000)
+
+
+
+
+.. parsed-literal::
+
+    105
+
+
+
+.. code:: ipython2
+
+    aoc20173(23000000000000)
+
+
+
+
+.. parsed-literal::
+
+    4572225
+
+
+
+Sympy to the Rescue
+===================
+
+Find the rank for large numbers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Using e.g. Sympy we can find the rank directly by solving for the roots
+of an equation. For large numbers this will (eventually) be faster than
+iterating as ``rank_and_offset()`` does.
+
+.. code:: ipython2
+
+    from sympy import floor, lambdify, solve, symbols
+    from sympy import init_printing
+    init_printing() 
+
+.. code:: ipython2
+
+    k = symbols('k')
+
+Since
+
+:math:`1 + 2 + 3 + ... + N = \frac{N(N + 1)}{2}`
+
+and
+
+:math:`\sum_{n=1}^k 8n = 8(\sum_{n=1}^k n) = 8\frac{k(k + 1)}{2}`
+
+We want:
+
+.. code:: ipython2
+
+    E = 2 + 8 * k * (k + 1) / 2  # For the reason for adding 2 see above.
+    
+    E
+
+
+
+
+.. math::
+
+    4 k \left(k + 1\right) + 2
+
+
+
+We can write a function to solve for :math:`k` given some :math:`n`...
+
+.. code:: ipython2
+
+    def rank_of(n):
+        return floor(max(solve(E - n, k))) + 1
+
+First ``solve()`` for :math:`E - n = 0` which has two solutions (because
+the equation is quadratic so it has two roots) and since we only care
+about the larger one we use ``max()`` to select it. It will generally
+not be a nice integer (unless :math:`n` is the number of an end-corner
+of a rank) so we take the ``floor()`` and add 1 to get the integer rank
+of :math:`n`. (Taking the ``ceiling()`` gives off-by-one errors on the
+rank boundaries. I don't know why. I'm basically like a monkey doing
+math here.) =-D
+
+It gives correct answers:
+
+.. code:: ipython2
+
+    for n in (9, 10, 25, 26, 49, 50):
+        print n, rank_of(n)
+
+
+.. parsed-literal::
+
+    9 1
+    10 2
+    25 2
+    26 3
+    49 3
+    50 4
+
+
+And it runs much faster (at least for large numbers):
+
+.. code:: ipython2
+
+    %time rank_of(23000000000000)  # Compare runtime with rank_and_offset()!
+
+
+.. parsed-literal::
+
+    CPU times: user 68 ms, sys: 8 ms, total: 76 ms
+    Wall time: 73.8 ms
+
+
+
+
+.. math::
+
+    2397916
+
+
+
+.. code:: ipython2
+
+    %time rank_and_offset(23000000000000)
+
+
+.. parsed-literal::
+
+    CPU times: user 308 ms, sys: 0 ns, total: 308 ms
+    Wall time: 306 ms
+
+
+
+
+.. math::
+
+    \left ( 2397916, \quad 223606\right )
+
+
+
+After finding the rank you would still have to find the actual value of
+the rank's first corner and subtract it (plus 2) from the number and
+compute the offset as above and then the final output, but this overhead
+is partially shared by the other method, and overshadowed by the time it
+(the other iterative method) would take for really big inputs.
+
+The fun thing to do here would be to graph the actual runtime of both
+methods against each other to find the trade-off point.
+
+It took me a second to realize I could do this...
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Sympy is a *symbolic* math library, and it supports symbolic
+manipulation of equations. I can put in :math:`y` (instead of a value)
+and ask it to solve for :math:`k`.
+
+.. code:: ipython2
+
+    y = symbols('y')
+
+.. code:: ipython2
+
+    g, f = solve(E - y, k)
+
+The equation is quadratic so there are two roots, we are interested in
+the greater one...
+
+.. code:: ipython2
+
+    g
+
+
+
+
+.. math::
+
+    - \frac{1}{2} \sqrt{y - 1} - \frac{1}{2}
+
+
+
+.. code:: ipython2
+
+    f
+
+
+
+
+.. math::
+
+    \frac{1}{2} \sqrt{y - 1} - \frac{1}{2}
+
+
+
+Now we can take the ``floor()``, add 1, and ``lambdify()`` the equation
+to get a Python function that calculates the rank directly.
+
+.. code:: ipython2
+
+    floor(f) + 1
+
+
+
+
+.. math::
+
+    \lfloor{\frac{1}{2} \sqrt{y - 1} - \frac{1}{2}}\rfloor + 1
+
+
+
+.. code:: ipython2
+
+    F = lambdify(y, floor(f) + 1)
+
+.. code:: ipython2
+
+    for n in (9, 10, 25, 26, 49, 50):
+        print n, int(F(n))
+
+
+.. parsed-literal::
+
+    9 1
+    10 2
+    25 2
+    26 3
+    49 3
+    50 4
+
+
+It's pretty fast.
+
+.. code:: ipython2
+
+    %time int(F(23000000000000))  # The clear winner.
+
+
+.. parsed-literal::
+
+    CPU times: user 0 ns, sys: 0 ns, total: 0 ns
+    Wall time: 11.9 µs
+
+
+
+
+.. math::
+
+    2397916
+
+
+
+Knowing the equation we could write our own function manually, but the
+speed is no better.
+
+.. code:: ipython2
+
+    from math import floor as mfloor, sqrt
+    
+    def mrank_of(n):
+        return int(mfloor(sqrt(23000000000000 - 1) / 2 - 0.5) + 1)
+
+.. code:: ipython2
+
+    %time mrank_of(23000000000000)
+
+
+.. parsed-literal::
+
+    CPU times: user 0 ns, sys: 0 ns, total: 0 ns
+    Wall time: 12.9 µs
+
+
+
+
+.. math::
+
+    2397916
+
+
+
+Given :math:`n` and a rank, compute the offset.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now that we have a fast way to get the rank, we still need to use it to
+compute the offset into a pyramid row.
+
+.. code:: ipython2
+
+    def offset_of(n, k):
+        return (n - 2 + 4 * k * (k - 1)) % (2 * k)
+
+(Note the sneaky way the sign changes from :math:`k(k + 1)` to
+:math:`k(k - 1)`. This is because we want to subract the
+:math:`(k - 1)`\ th rank's total places (its own and those of lesser
+rank) from our :math:`n` of rank :math:`k`. Substituting :math:`k - 1`
+for :math:`k` in :math:`k(k + 1)` gives :math:`(k - 1)(k - 1 + 1)`,
+which of course simplifies to :math:`k(k - 1)`.)
+
+.. code:: ipython2
+
+    offset_of(23000000000000, 2397916)
+
+
+
+
+.. math::
+
+    223606
+
+
+
+So, we can compute the rank, then the offset, then the row value.
+
+.. code:: ipython2
+
+    def rank_of(n):
+        return int(mfloor(sqrt(n - 1) / 2 - 0.5) + 1)
+    
+    
+    def offset_of(n, k):
+        return (n - 2 + 4 * k * (k - 1)) % (2 * k)
+    
+    
+    def row_value(k, i):
+        return abs(i - (k - 1)) + k
+    
+    
+    def aoc20173(n):
+        k = rank_of(n)
+        i = offset_of(n, k)
+        return row_value(k, i)
+
+.. code:: ipython2
+
+    aoc20173(23)
+
+
+
+
+.. math::
+
+    2
+
+
+
+.. code:: ipython2
+
+    aoc20173(23000)
+
+
+
+
+.. math::
+
+    105
+
+
+
+.. code:: ipython2
+
+    aoc20173(23000000000000)
+
+
+
+
+.. math::
+
+    4572225
+
+
+
+.. code:: ipython2
+
+    %time aoc20173(23000000000000000000000000)  # Fast for large values.
+
+
+.. parsed-literal::
+
+    CPU times: user 0 ns, sys: 0 ns, total: 0 ns
+    Wall time: 20 µs
+
+
+
+
+.. math::
+
+    2690062495969
+
+
+
+A Joy Version
+=============
+
+At this point I feel confident that I can implement a concise version of
+this code in Joy. ;-)
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+``rank_of``
+~~~~~~~~~~~
+
+::
+
+       n rank_of
+    ---------------
+          k
+
+The translation is straightforward.
+
+::
+
+    int(floor(sqrt(n - 1) / 2 - 0.5) + 1)
+
+    rank_of == -- sqrt 2 / 0.5 - floor ++
+
+.. code:: ipython2
+
+    define('rank_of == -- sqrt 2 / 0.5 - floor ++')
+
+``offset_of``
+~~~~~~~~~~~~~
+
+::
+
+       n k offset_of
+    -------------------
+             i
+
+    (n - 2 + 4 * k * (k - 1)) % (2 * k)
+
+A little tricky...
+
+::
+
+    n k dup 2 *
+    n k k 2 *
+    n k k*2 [Q] dip %
+    n k Q k*2 %
+
+    n k dup --
+    n k k --
+    n k k-1 4 * * 2 + -
+    n k*k-1*4     2 + -
+    n k*k-1*4+2       -
+    n-k*k-1*4+2
+
+    n-k*k-1*4+2 k*2 %
+    n-k*k-1*4+2%k*2
+
+Ergo:
+
+::
+
+    offset_of == dup 2 * [dup -- 4 * * 2 + -] dip %
+
+.. code:: ipython2
+
+    define('offset_of == dup 2 * [dup -- 4 * * 2 + -] dip %')
+
+``row_value``
+~~~~~~~~~~~~~
+
+::
+
+       k i row_value
+    -------------------
+            n
+
+    abs(i - (k - 1)) + k
+
+    k i over -- - abs +
+    k i k    -- - abs +
+    k i k-1     - abs +
+    k i-k-1       abs +
+    k |i-k-1|         +
+    k+|i-k-1|
+
+.. code:: ipython2
+
+    define('row_value == over -- - abs +')
+
+``aoc2017.3``
+~~~~~~~~~~~~~
+
+::
+
+       n aoc2017.3
+    -----------------
+            m
+
+    n dup rank_of
+    n k [offset_of] dupdip
+    n k offset_of k
+    i             k swap row_value
+    k i row_value
+    m
+
+.. code:: ipython2
+
+    define('aoc2017.3 == dup rank_of [offset_of] dupdip swap row_value')
+
+.. code:: ipython2
+
+    J('23 aoc2017.3')
+
+
+.. parsed-literal::
+
+    2
+
+
+.. code:: ipython2
+
+    J('23000 aoc2017.3')
+
+
+.. parsed-literal::
+
+    105
+
+
+.. code:: ipython2
+
+    V('23000000000000 aoc2017.3')
+
+
+.. parsed-literal::
+
+                                                        . 23000000000000 aoc2017.3
+                                         23000000000000 . aoc2017.3
+                                         23000000000000 . dup rank_of [offset_of] dupdip swap row_value
+                          23000000000000 23000000000000 . rank_of [offset_of] dupdip swap row_value
+                          23000000000000 23000000000000 . -- sqrt 2 / 0.5 - floor ++ [offset_of] dupdip swap row_value
+                          23000000000000 22999999999999 . sqrt 2 / 0.5 - floor ++ [offset_of] dupdip swap row_value
+                       23000000000000 4795831.523312615 . 2 / 0.5 - floor ++ [offset_of] dupdip swap row_value
+                     23000000000000 4795831.523312615 2 . / 0.5 - floor ++ [offset_of] dupdip swap row_value
+                      23000000000000 2397915.7616563076 . 0.5 - floor ++ [offset_of] dupdip swap row_value
+                  23000000000000 2397915.7616563076 0.5 . - floor ++ [offset_of] dupdip swap row_value
+                      23000000000000 2397915.2616563076 . floor ++ [offset_of] dupdip swap row_value
+                                 23000000000000 2397915 . ++ [offset_of] dupdip swap row_value
+                                 23000000000000 2397916 . [offset_of] dupdip swap row_value
+                     23000000000000 2397916 [offset_of] . dupdip swap row_value
+                                 23000000000000 2397916 . offset_of 2397916 swap row_value
+                                 23000000000000 2397916 . dup 2 * [dup -- 4 * * 2 + -] dip % 2397916 swap row_value
+                         23000000000000 2397916 2397916 . 2 * [dup -- 4 * * 2 + -] dip % 2397916 swap row_value
+                       23000000000000 2397916 2397916 2 . * [dup -- 4 * * 2 + -] dip % 2397916 swap row_value
+                         23000000000000 2397916 4795832 . [dup -- 4 * * 2 + -] dip % 2397916 swap row_value
+    23000000000000 2397916 4795832 [dup -- 4 * * 2 + -] . dip % 2397916 swap row_value
+                                 23000000000000 2397916 . dup -- 4 * * 2 + - 4795832 % 2397916 swap row_value
+                         23000000000000 2397916 2397916 . -- 4 * * 2 + - 4795832 % 2397916 swap row_value
+                         23000000000000 2397916 2397915 . 4 * * 2 + - 4795832 % 2397916 swap row_value
+                       23000000000000 2397916 2397915 4 . * * 2 + - 4795832 % 2397916 swap row_value
+                         23000000000000 2397916 9591660 . * 2 + - 4795832 % 2397916 swap row_value
+                          23000000000000 22999994980560 . 2 + - 4795832 % 2397916 swap row_value
+                        23000000000000 22999994980560 2 . + - 4795832 % 2397916 swap row_value
+                          23000000000000 22999994980562 . - 4795832 % 2397916 swap row_value
+                                                5019438 . 4795832 % 2397916 swap row_value
+                                        5019438 4795832 . % 2397916 swap row_value
+                                                 223606 . 2397916 swap row_value
+                                         223606 2397916 . swap row_value
+                                         2397916 223606 . row_value
+                                         2397916 223606 . over -- - abs +
+                                 2397916 223606 2397916 . -- - abs +
+                                 2397916 223606 2397915 . - abs +
+                                       2397916 -2174309 . abs +
+                                        2397916 2174309 . +
+                                                4572225 . 
+
+
+::
+
+      rank_of == -- sqrt 2 / 0.5 - floor ++
+    offset_of == dup 2 * [dup -- 4 * * 2 + -] dip %
+    row_value == over -- - abs +
+
+    aoc2017.3 == dup rank_of [offset_of] dupdip swap row_value
diff --git a/docs/Advent of Code 2017 December 4th.rst b/docs/Advent of Code 2017 December 4th.rst
new file mode 100644 (file)
index 0000000..e51ca12
--- /dev/null
@@ -0,0 +1,77 @@
+
+Advent of Code 2017
+===================
+
+December 4th
+------------
+
+To ensure security, a valid passphrase must contain no duplicate words.
+
+For example:
+
+-  aa bb cc dd ee is valid.
+-  aa bb cc dd aa is not valid - the word aa appears more than once.
+-  aa bb cc dd aaa is valid - aa and aaa count as different words.
+
+The system's full passphrase list is available as your puzzle input. How
+many passphrases are valid?
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+I'll assume the input is a Joy sequence of sequences of integers.
+
+::
+
+    [[5 1 9 5]
+     [7 5 4 3]
+     [2 4 6 8]]
+
+So, obviously, the initial form will be a ``step`` function:
+
+::
+
+    AoC2017.4 == 0 swap [F +] step
+
+::
+
+    F == [size] [unique size] cleave =
+
+The ``step_zero`` combinator includes the ``0 swap`` that would normally
+open one of these definitions:
+
+.. code:: ipython2
+
+    J('[step_zero] help')
+
+
+.. parsed-literal::
+
+    0 roll> step
+    
+
+
+::
+
+    AoC2017.4 == [F +] step_zero
+
+.. code:: ipython2
+
+    define('AoC2017.4 == [[size] [unique size] cleave = +] step_zero')
+
+.. code:: ipython2
+
+    J('''
+    
+    [[5 1 9 5]
+     [7 5 4 3]
+     [2 4 6 8]] AoC2017.4
+    
+    ''')
+
+
+.. parsed-literal::
+
+    2
+
diff --git a/docs/Advent of Code 2017 December 5th.rst b/docs/Advent of Code 2017 December 5th.rst
new file mode 100644 (file)
index 0000000..5040c69
--- /dev/null
@@ -0,0 +1,324 @@
+
+Advent of Code 2017
+===================
+
+December 5th
+------------
+
+...a list of the offsets for each jump. Jumps are relative: -1 moves to
+the previous instruction, and 2 skips the next one. Start at the first
+instruction in the list. The goal is to follow the jumps until one leads
+outside the list.
+
+In addition, these instructions are a little strange; after each jump,
+the offset of that instruction increases by 1. So, if you come across an
+offset of 3, you would move three instructions forward, but change it to
+a 4 for the next time it is encountered.
+
+For example, consider the following list of jump offsets:
+
+::
+
+    0
+    3
+    0
+    1
+    -3
+
+Positive jumps ("forward") move downward; negative jumps move upward.
+For legibility in this example, these offset values will be written all
+on one line, with the current instruction marked in parentheses. The
+following steps would be taken before an exit is found:
+
+-  
+
+   (0) 3 0 1 -3 - before we have taken any steps.
+
+-  
+
+   (1) 3 0 1 -3 - jump with offset 0 (that is, don't jump at all).
+       Fortunately, the instruction is then incremented to 1.
+
+-  2 (3) 0 1 -3 - step forward because of the instruction we just
+   modified. The first instruction is incremented again, now to 2.
+-  2 4 0 1 (-3) - jump all the way to the end; leave a 4 behind.
+-  2 (4) 0 1 -2 - go back to where we just were; increment -3 to -2.
+-  2 5 0 1 -2 - jump 4 steps forward, escaping the maze.
+
+In this example, the exit is reached in 5 steps.
+
+How many steps does it take to reach the exit?
+
+Breakdown
+---------
+
+For now, I'm going to assume a starting state with the size of the
+sequence pre-computed. We need it to define the exit condition and it is
+a trivial preamble to generate it. We then need and ``index`` and a
+``step-count``, which are both initially zero. Then we have the sequence
+itself, and some recursive function ``F`` that does the work.
+
+::
+
+       size index step-count [...] F
+    -----------------------------------
+                step-count
+
+    F == [P] [T] [R1] [R2] genrec
+
+Later on I was thinking about it and the Forth heuristic came to mind,
+to wit: four things on the stack are kind of much. Immediately I
+realized that the size properly belongs in the predicate of ``F``! D'oh!
+
+::
+
+       index step-count [...] F
+    ------------------------------
+             step-count
+
+So, let's start by nailing down the predicate:
+
+::
+
+    F == [P] [T] [R1]   [R2] genrec
+      == [P] [T] [R1 [F] R2] ifte
+
+    0 0 [0 3 0 1 -3] popop 5 >=
+
+    P == popop 5 >=
+
+Now we need the else-part:
+
+::
+
+    index step-count [0 3 0 1 -3] roll< popop
+
+    E == roll< popop
+
+Last but not least, the recursive branch
+
+::
+
+    0 0 [0 3 0 1 -3] R1 [F] R2
+
+The ``R1`` function has a big job:
+
+::
+
+    R1 == get the value at index
+          increment the value at the index
+          add the value gotten to the index
+          increment the step count
+
+The only tricky thing there is incrementing an integer in the sequence.
+Joy sequences are not particularly good for random access. We could
+encode the list of jump offsets in a big integer and use math to do the
+processing for a good speed-up, but it still wouldn't beat the
+performance of e.g. a mutable array. This is just one of those places
+where "plain vanilla" Joypy doesn't shine (in default performance. The
+legendary *Sufficiently-Smart Compiler* would of course rewrite this
+function to use an array "under the hood".)
+
+In the meantime, I'm going to write a primitive function that just does
+what we need.
+
+.. code:: ipython2
+
+    from notebook_preamble import D, J, V, define
+    from joy.library import SimpleFunctionWrapper
+    from joy.utils.stack import list_to_stack
+    
+    
+    @SimpleFunctionWrapper
+    def incr_at(stack):
+        '''Given a index and a sequence of integers, increment the integer at the index.
+    
+        E.g.:
+    
+           3 [0 1 2 3 4 5] incr_at
+        -----------------------------
+             [0 1 2 4 4 5]
+        
+        '''
+        sequence, (i, stack) = stack
+        mem = []
+        while i >= 0:
+            term, sequence = sequence
+            mem.append(term)
+            i -= 1
+        mem[-1] += 1
+        return list_to_stack(mem, sequence), stack
+    
+    
+    D['incr_at'] = incr_at
+
+.. code:: ipython2
+
+    J('3 [0 1 2 3 4 5] incr_at')
+
+
+.. parsed-literal::
+
+    [0 1 2 4 4 5]
+
+
+get the value at index
+~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    3 0 [0 1 2 3 4] [roll< at] nullary
+    3 0 [0 1 2 n 4] n
+
+increment the value at the index
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    3 0 [0 1 2 n 4] n [Q] dip
+    3 0 [0 1 2 n 4] Q n
+    3 0 [0 1 2 n 4] [popd incr_at] unary n
+    3 0 [0 1 2 n+1 4] n
+
+add the value gotten to the index
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    3 0 [0 1 2 n+1 4] n [+] cons dipd
+    3 0 [0 1 2 n+1 4] [n +]      dipd
+    3 n + 0 [0 1 2 n+1 4]
+    3+n   0 [0 1 2 n+1 4]
+
+increment the step count
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    3+n 0 [0 1 2 n+1 4] [++] dip
+    3+n 1 [0 1 2 n+1 4]
+
+All together now...
+~~~~~~~~~~~~~~~~~~~
+
+::
+
+    get_value == [roll< at] nullary
+    incr_value == [[popd incr_at] unary] dip
+    add_value == [+] cons dipd
+    incr_step_count == [++] dip
+
+    R1 == get_value incr_value add_value incr_step_count
+
+    F == [P] [T] [R1] primrec
+
+    F == [popop !size! >=] [roll< pop] [get_value incr_value add_value incr_step_count] primrec
+
+.. code:: ipython2
+
+    from joy.library import DefinitionWrapper
+    
+    
+    DefinitionWrapper.add_definitions('''
+    
+          get_value == [roll< at] nullary
+         incr_value == [[popd incr_at] unary] dip
+          add_value == [+] cons dipd
+    incr_step_count == [++] dip
+    
+         AoC2017.5.0 == get_value incr_value add_value incr_step_count
+    
+    ''', D)
+
+.. code:: ipython2
+
+    define('F == [popop 5 >=] [roll< popop] [AoC2017.5.0] primrec')
+
+.. code:: ipython2
+
+    J('0 0 [0 3 0 1 -3] F')
+
+
+.. parsed-literal::
+
+    5
+
+
+Preamble for setting up predicate, ``index``, and ``step-count``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We want to go from this to this:
+
+::
+
+       [...] AoC2017.5.preamble
+    ------------------------------
+        0 0 [...] [popop n >=]
+
+Where ``n`` is the size of the sequence.
+
+The first part is obviously ``0 0 roll<``, then ``dup size``:
+
+::
+
+    [...] 0 0 roll< dup size
+    0 0 [...] n
+
+Then:
+
+::
+
+    0 0 [...] n [>=] cons [popop] swoncat
+
+So:
+
+::
+
+    init-index-and-step-count == 0 0 roll<
+    prepare-predicate == dup size [>=] cons [popop] swoncat
+
+    AoC2017.5.preamble == init-index-and-step-count prepare-predicate
+
+.. code:: ipython2
+
+    DefinitionWrapper.add_definitions('''
+    
+    init-index-and-step-count == 0 0 roll<
+            prepare-predicate == dup size [>=] cons [popop] swoncat
+    
+           AoC2017.5.preamble == init-index-and-step-count prepare-predicate
+    
+                    AoC2017.5 == AoC2017.5.preamble [roll< popop] [AoC2017.5.0] primrec
+    
+    ''', D)
+
+.. code:: ipython2
+
+    J('[0 3 0 1 -3] AoC2017.5')
+
+
+.. parsed-literal::
+
+    5
+
+
+::
+
+                    AoC2017.5 == AoC2017.5.preamble [roll< popop] [AoC2017.5.0] primrec
+
+                  AoC2017.5.0 == get_value incr_value add_value incr_step_count
+           AoC2017.5.preamble == init-index-and-step-count prepare-predicate
+
+                    get_value == [roll< at] nullary
+                   incr_value == [[popd incr_at] unary] dip
+                    add_value == [+] cons dipd
+              incr_step_count == [++] dip
+
+    init-index-and-step-count == 0 0 roll<
+            prepare-predicate == dup size [>=] cons [popop] swoncat
+
+This is by far the largest program I have yet written in Joy. Even with
+the ``incr_at`` function it is still a bear. There may be an arrangement
+of the parameters that would permit more elegant definitions, but it
+still wouldn't be as efficient as something written in assembly, C, or
+even Python.
diff --git a/docs/Advent of Code 2017 December 6th.rst b/docs/Advent of Code 2017 December 6th.rst
new file mode 100644 (file)
index 0000000..5da2f1b
--- /dev/null
@@ -0,0 +1,305 @@
+
+Advent of Code 2017
+===================
+
+December 6th
+------------
+
+::
+
+    [0 2 7 0] dup max
+
+.. code:: ipython2
+
+    from notebook_preamble import D, J, V, define
+
+.. code:: ipython2
+
+    J('[0 2 7 0] dup max')
+
+
+.. parsed-literal::
+
+    [0 2 7 0] 7
+
+
+.. code:: ipython2
+
+    from joy.library import SimpleFunctionWrapper
+    from joy.utils.stack import list_to_stack
+    
+    
+    @SimpleFunctionWrapper
+    def index_of(stack):
+        '''Given a sequence and a item, return the index of the item, or -1 if not found.
+    
+        E.g.:
+    
+           [a b c] a index_of
+        ------------------------
+                   0
+    
+           [a b c] d index_of
+        ------------------------
+                -1
+    
+        '''
+        item, (sequence, stack) = stack
+        i = 0
+        while sequence:
+            term, sequence = sequence
+            if term == item:
+                break
+            i += 1
+        else:
+            i = -1
+        return i, stack
+    
+    
+    D['index_of'] = index_of
+
+.. code:: ipython2
+
+    J('[0 2 7 0] 7 index_of')
+
+
+.. parsed-literal::
+
+    2
+
+
+.. code:: ipython2
+
+    J('[0 2 7 0] 23 index_of')
+
+
+.. parsed-literal::
+
+    -1
+
+
+Starting at ``index`` distribute ``count`` "blocks" to the "banks" in
+the sequence.
+
+::
+
+    [...] count index distribute
+    ----------------------------
+               [...]
+
+This seems like it would be a PITA to implement in Joypy...
+
+.. code:: ipython2
+
+    from joy.utils.stack import iter_stack, list_to_stack
+    
+    
+    @SimpleFunctionWrapper
+    def distribute(stack):
+        '''Starting at index+1 distribute count "blocks" to the "banks" in the sequence.
+    
+        [...] count index distribute
+        ----------------------------
+                   [...]
+    
+        '''
+        index, (count, (sequence, stack)) = stack
+        assert count >= 0
+        cheat = list(iter_stack(sequence))
+        n = len(cheat)
+        assert index < n
+        cheat[index] = 0
+        while count:
+            index += 1
+            index %= n
+            cheat[index] += 1
+            count -= 1
+        return list_to_stack(cheat), stack
+    
+    
+    D['distribute'] = distribute
+
+.. code:: ipython2
+
+    J('[0 2 7 0] dup max [index_of] nullary distribute')
+
+
+.. parsed-literal::
+
+    [2 4 1 2]
+
+
+.. code:: ipython2
+
+    J('[2 4 1 2] dup max [index_of] nullary distribute')
+
+
+.. parsed-literal::
+
+    [3 1 2 3]
+
+
+.. code:: ipython2
+
+    J('[3 1 2 3] dup max [index_of] nullary distribute')
+
+
+.. parsed-literal::
+
+    [0 2 3 4]
+
+
+.. code:: ipython2
+
+    J('[0 2 3 4] dup max [index_of] nullary distribute')
+
+
+.. parsed-literal::
+
+    [1 3 4 1]
+
+
+.. code:: ipython2
+
+    J('[1 3 4 1] dup max [index_of] nullary distribute')
+
+
+.. parsed-literal::
+
+    [2 4 1 2]
+
+
+Recalling "Generator Programs"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    [a F] x
+    [a F] a F 
+
+    [a F] a swap [C] dip rest cons
+    a   [a F]    [C] dip rest cons
+    a C [a F]            rest cons
+    a C   [F]                 cons
+
+    w/ C == dup G
+
+    a dup G [F] cons
+    a a   G [F] cons
+
+    w/ G == dup max [index_of] nullary distribute
+
+.. code:: ipython2
+
+    define('direco == dip rest cons')
+
+.. code:: ipython2
+
+    define('G == [direco] cons [swap] swoncat cons')
+
+.. code:: ipython2
+
+    define('make_distributor == [dup dup max [index_of] nullary distribute] G')
+
+.. code:: ipython2
+
+    J('[0 2 7 0] make_distributor 6 [x] times pop')
+
+
+.. parsed-literal::
+
+    [0 2 7 0] [2 4 1 2] [3 1 2 3] [0 2 3 4] [1 3 4 1] [2 4 1 2]
+
+
+A function to drive a generator and count how many states before a repeat.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+First draft:
+
+::
+
+    [] [GEN] x [pop index_of 0 >=] [pop size --] [[swons] dip x] primrec
+
+(?)
+
+::
+
+    []       [GEN] x [pop index_of 0 >=] [pop size --] [[swons] dip x] primrec
+    [] [...] [GEN]   [pop index_of 0 >=] [pop size --] [[swons] dip x] primrec
+    [] [...] [GEN]    pop index_of 0 >=
+    [] [...]              index_of 0 >=
+                                -1 0 >=
+                                 False
+
+Base case
+
+::
+
+    [] [...] [GEN] [pop index_of 0 >=] [pop size --] [[swons] dip x] primrec
+    [] [...] [GEN]                      pop size --
+    [] [...]                                size --
+    [] [...]                                size --
+
+A mistake, ``popop`` and no need for ``--``
+
+::
+
+    [] [...] [GEN] popop size
+    []                   size
+    n
+
+Recursive case
+
+::
+
+    [] [...] [GEN] [pop index_of 0 >=] [popop size] [[swons] dip x] primrec
+    [] [...] [GEN]                                   [swons] dip x  F
+    [] [...] swons [GEN]                                         x  F
+    [[...]]        [GEN]                                         x  F
+    [[...]] [...]  [GEN]                                            F
+
+    [[...]] [...] [GEN] F
+
+What have we learned?
+
+::
+
+    F == [pop index_of 0 >=] [popop size] [[swons] dip x] primrec
+
+.. code:: ipython2
+
+    define('count_states == [] swap x [pop index_of 0 >=] [popop size] [[swons] dip x] primrec')
+
+.. code:: ipython2
+
+    define('AoC2017.6 == make_distributor count_states')
+
+.. code:: ipython2
+
+    J('[0 2 7 0] AoC2017.6')
+
+
+.. parsed-literal::
+
+    5
+
+
+.. code:: ipython2
+
+    J('[1 1 1] AoC2017.6')
+
+
+.. parsed-literal::
+
+    4
+
+
+.. code:: ipython2
+
+    J('[8 0 0 0 0 0] AoC2017.6')
+
+
+.. parsed-literal::
+
+    15
+
diff --git a/docs/Generator Programs.rst b/docs/Generator Programs.rst
new file mode 100644 (file)
index 0000000..f1b99a6
--- /dev/null
@@ -0,0 +1,675 @@
+
+Using ``x`` to Generate Values
+==============================
+
+Cf. jp-reprod.html
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+Consider the ``x`` combinator ``x == dup i``:
+
+::
+
+    [a B] x
+    [a B] a B
+
+Let ``B`` ``swap`` the ``a`` with the quote and run some function
+``[C]`` on it.
+
+::
+
+    [a B] a B
+    [a B] a swap [C] dip
+    a [a B]      [C] dip
+    a C [a B]
+
+Now discard the quoted ``a`` with ``rest`` and ``cons`` the result of
+``C`` on ``a`` whatever that is:
+
+::
+
+    aC [a B] rest cons
+    aC [B] cons
+    [aC B]
+
+Altogether, this is the definition of ``B``:
+
+::
+
+    B == swap [C] dip rest cons
+
+We can create a quoted program that generates the Natural numbers
+(integers 0, 1, 2, ...) by using ``0`` for ``a`` and ``[dup ++]`` for
+``[C]``:
+
+::
+
+    [0 swap [dup ++] dip rest cons]
+
+Let's try it:
+
+.. code:: ipython2
+
+    V('[0 swap [dup ++] dip rest cons] x')
+
+
+.. parsed-literal::
+
+                                               . [0 swap [dup ++] dip rest cons] x
+               [0 swap [dup ++] dip rest cons] . x
+               [0 swap [dup ++] dip rest cons] . 0 swap [dup ++] dip rest cons
+             [0 swap [dup ++] dip rest cons] 0 . swap [dup ++] dip rest cons
+             0 [0 swap [dup ++] dip rest cons] . [dup ++] dip rest cons
+    0 [0 swap [dup ++] dip rest cons] [dup ++] . dip rest cons
+                                             0 . dup ++ [0 swap [dup ++] dip rest cons] rest cons
+                                           0 0 . ++ [0 swap [dup ++] dip rest cons] rest cons
+                                           0 1 . [0 swap [dup ++] dip rest cons] rest cons
+           0 1 [0 swap [dup ++] dip rest cons] . rest cons
+             0 1 [swap [dup ++] dip rest cons] . cons
+             0 [1 swap [dup ++] dip rest cons] . 
+
+
+After one application of ``x`` the quoted program contains ``1`` and
+``0`` is below it on the stack.
+
+.. code:: ipython2
+
+    J('[0 swap [dup ++] dip rest cons] x x x x x pop')
+
+
+.. parsed-literal::
+
+    0 1 2 3 4
+
+
+``direco``
+~~~~~~~~~~
+
+.. code:: ipython2
+
+    define('direco == dip rest cons')
+
+.. code:: ipython2
+
+    V('[0 swap [dup ++] direco] x')
+
+
+.. parsed-literal::
+
+                                        . [0 swap [dup ++] direco] x
+               [0 swap [dup ++] direco] . x
+               [0 swap [dup ++] direco] . 0 swap [dup ++] direco
+             [0 swap [dup ++] direco] 0 . swap [dup ++] direco
+             0 [0 swap [dup ++] direco] . [dup ++] direco
+    0 [0 swap [dup ++] direco] [dup ++] . direco
+    0 [0 swap [dup ++] direco] [dup ++] . dip rest cons
+                                      0 . dup ++ [0 swap [dup ++] direco] rest cons
+                                    0 0 . ++ [0 swap [dup ++] direco] rest cons
+                                    0 1 . [0 swap [dup ++] direco] rest cons
+           0 1 [0 swap [dup ++] direco] . rest cons
+             0 1 [swap [dup ++] direco] . cons
+             0 [1 swap [dup ++] direco] . 
+
+
+Generating Generators
+=====================
+
+We want to go from:
+
+::
+
+    a [C] G
+
+to:
+
+::
+
+    [a swap [C] direco]
+
+Working in reverse:
+
+::
+
+    [a swap   [C] direco] cons
+    a [swap   [C] direco] concat
+    a [swap] [[C] direco] swap
+    a [[C] direco] [swap]
+    a [C] [direco] cons [swap]
+
+Reading from the bottom up:
+
+::
+
+    G == [direco] cons [swap] swap concat cons
+    G == [direco] cons [swap] swoncat cons
+
+We can try it out:
+
+::
+
+    0 [dup ++] G
+
+.. code:: ipython2
+
+    define('G == [direco] cons [swap] swoncat cons')
+
+.. code:: ipython2
+
+    V('0 [dup ++] G')
+
+
+.. parsed-literal::
+
+                               . 0 [dup ++] G
+                             0 . [dup ++] G
+                    0 [dup ++] . G
+                    0 [dup ++] . [direco] cons [swap] swoncat cons
+           0 [dup ++] [direco] . cons [swap] swoncat cons
+           0 [[dup ++] direco] . [swap] swoncat cons
+    0 [[dup ++] direco] [swap] . swoncat cons
+    0 [[dup ++] direco] [swap] . swap concat cons
+    0 [swap] [[dup ++] direco] . concat cons
+      0 [swap [dup ++] direco] . cons
+      [0 swap [dup ++] direco] . 
+
+
+.. code:: ipython2
+
+    V('0 [dup ++] G x')
+
+
+.. parsed-literal::
+
+                                        . 0 [dup ++] G x
+                                      0 . [dup ++] G x
+                             0 [dup ++] . G x
+                             0 [dup ++] . [direco] cons [swap] swoncat cons x
+                    0 [dup ++] [direco] . cons [swap] swoncat cons x
+                    0 [[dup ++] direco] . [swap] swoncat cons x
+             0 [[dup ++] direco] [swap] . swoncat cons x
+             0 [[dup ++] direco] [swap] . swap concat cons x
+             0 [swap] [[dup ++] direco] . concat cons x
+               0 [swap [dup ++] direco] . cons x
+               [0 swap [dup ++] direco] . x
+               [0 swap [dup ++] direco] . 0 swap [dup ++] direco
+             [0 swap [dup ++] direco] 0 . swap [dup ++] direco
+             0 [0 swap [dup ++] direco] . [dup ++] direco
+    0 [0 swap [dup ++] direco] [dup ++] . direco
+    0 [0 swap [dup ++] direco] [dup ++] . dip rest cons
+                                      0 . dup ++ [0 swap [dup ++] direco] rest cons
+                                    0 0 . ++ [0 swap [dup ++] direco] rest cons
+                                    0 1 . [0 swap [dup ++] direco] rest cons
+           0 1 [0 swap [dup ++] direco] . rest cons
+             0 1 [swap [dup ++] direco] . cons
+             0 [1 swap [dup ++] direco] . 
+
+
+Powers of 2
+~~~~~~~~~~~
+
+.. code:: ipython2
+
+    J('1 [dup 1 <<] G x x x x x x x x x')
+
+
+.. parsed-literal::
+
+    1 2 4 8 16 32 64 128 256 [512 swap [dup 1 <<] direco]
+
+
+``n [x] times``
+===============
+
+If we have one of these quoted programs we can drive it using ``times``
+with the ``x`` combinator.
+
+Let's define a word ``n_range`` that takes a starting integer and a
+count and leaves that many consecutive integers on the stack. For
+example:
+
+.. code:: ipython2
+
+    J('23 [dup ++] G 5 [x] times pop')
+
+
+.. parsed-literal::
+
+    23 24 25 26 27
+
+
+We can use ``dip`` to untangle ``[dup ++] G`` from the arguments.
+
+.. code:: ipython2
+
+    J('23 5 [[dup ++] G] dip [x] times pop')
+
+
+.. parsed-literal::
+
+    23 24 25 26 27
+
+
+Now that the givens (arguments) are on the left we have the definition
+we're looking for:
+
+.. code:: ipython2
+
+    define('n_range == [[dup ++] G] dip [x] times pop')
+
+.. code:: ipython2
+
+    J('450 10 n_range')
+
+
+.. parsed-literal::
+
+    450 451 452 453 454 455 456 457 458 459
+
+
+This is better just using the ``times`` combinator though...
+
+.. code:: ipython2
+
+    J('450 9 [dup ++] times')
+
+
+.. parsed-literal::
+
+    450 451 452 453 454 455 456 457 458 459
+
+
+Generating Multiples of Three and Five
+======================================
+
+Look at the treatment of the Project Euler Problem One in `Developing a
+Program.ipynb <./Developing%20a%20Program.ipynb>`__ and you'll see that
+we might be interested in generating an endless cycle of:
+
+::
+
+    3 2 1 3 1 2 3
+
+To do this we want to encode the numbers as pairs of bits in a single
+int:
+
+::
+
+        3  2  1  3  1  2  3
+    0b 11 10 01 11 01 10 11 == 14811
+
+And pick them off by masking with 3 (binary 11) and then shifting the
+int right two bits.
+
+.. code:: ipython2
+
+    define('PE1.1 == dup [3 &] dip 2 >>')
+
+.. code:: ipython2
+
+    V('14811 PE1.1')
+
+
+.. parsed-literal::
+
+                      . 14811 PE1.1
+                14811 . PE1.1
+                14811 . dup [3 &] dip 2 >>
+          14811 14811 . [3 &] dip 2 >>
+    14811 14811 [3 &] . dip 2 >>
+                14811 . 3 & 14811 2 >>
+              14811 3 . & 14811 2 >>
+                    3 . 14811 2 >>
+              3 14811 . 2 >>
+            3 14811 2 . >>
+               3 3702 . 
+
+
+If we plug ``14811`` and ``[PE1.1]`` into our generator form...
+
+.. code:: ipython2
+
+    J('14811 [PE1.1] G')
+
+
+.. parsed-literal::
+
+    [14811 swap [PE1.1] direco]
+
+
+.. code:: ipython2
+
+    J('[14811 swap [PE1.1] direco] x')
+
+
+.. parsed-literal::
+
+    3 [3702 swap [PE1.1] direco]
+
+
+...we get a generator that works for seven cycles before it reaches
+zero:
+
+.. code:: ipython2
+
+    J('[14811 swap [PE1.1] direco] 7 [x] times')
+
+
+.. parsed-literal::
+
+    3 2 1 3 1 2 3 [0 swap [PE1.1] direco]
+
+
+Reset at Zero
+~~~~~~~~~~~~~
+
+We need a function that checks if the int has reached zero and resets it
+if so.
+
+.. code:: ipython2
+
+    define('PE1.1.check == dup [pop 14811] [] branch')
+
+.. code:: ipython2
+
+    J('[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times')
+
+
+.. parsed-literal::
+
+    3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 [0 swap [PE1.1.check PE1.1] direco]
+
+
+Run 466 times
+~~~~~~~~~~~~~
+
+In the PE1 problem we are asked to sum all the multiples of three and
+five less than 1000. It's worked out that we need to use all seven
+numbers sixty-six times and then four more.
+
+.. code:: ipython2
+
+    J('7 66 * 4 +')
+
+
+.. parsed-literal::
+
+    466
+
+
+If we drive our generator 466 times and sum the stack we get 999.
+
+.. code:: ipython2
+
+    J('[14811 swap [PE1.1.check PE1.1] dip rest cons] 466 [x] times')
+
+
+.. parsed-literal::
+
+    3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 [57 swap [PE1.1.check PE1.1] dip rest cons]
+
+
+.. code:: ipython2
+
+    J('[14811 swap [PE1.1.check PE1.1] dip rest cons] 466 [x] times pop enstacken sum')
+
+
+.. parsed-literal::
+
+    999
+
+
+Project Euler Problem One
+=========================
+
+.. code:: ipython2
+
+    define('PE1.2 == + dup [+] dip')
+
+Now we can add ``PE1.2`` to the quoted program given to ``times``.
+
+.. code:: ipython2
+
+    J('0 0 [0 swap [PE1.1.check PE1.1] direco] 466 [x [PE1.2] dip] times popop')
+
+
+.. parsed-literal::
+
+    233168
+
+
+Or using ``G`` we can write:
+
+.. code:: ipython2
+
+    J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')
+
+
+.. parsed-literal::
+
+    233168
+
+
+A generator for the Fibonacci Sequence.
+=======================================
+
+Consider:
+
+::
+
+    [b a F] x
+    [b a F] b a F
+
+The obvious first thing to do is just add ``b`` and ``a``:
+
+::
+
+    [b a F] b a +
+    [b a F] b+a
+
+From here we want to arrive at:
+
+::
+
+    b [b+a b F]
+
+Let's start with ``swons``:
+
+::
+
+    [b a F] b+a swons
+    [b+a b a F]
+
+Considering this quote as a stack:
+
+::
+
+    F a b b+a
+
+We want to get it to:
+
+::
+
+    F b b+a b
+
+So:
+
+::
+
+    F a b b+a popdd over
+    F b b+a b
+
+And therefore:
+
+::
+
+    [b+a b a F] [popdd over] infra
+    [b b+a b F]
+
+And lastly:
+
+::
+
+    [b b+a b F] uncons
+    b [b+a b F]
+
+Done.
+
+Putting it all together:
+
+::
+
+    F == + swons [popdd over] infra uncons
+
+And:
+
+::
+
+    fib_gen == [1 1 F]
+
+.. code:: ipython2
+
+    define('fib == + swons [popdd over] infra uncons')
+
+.. code:: ipython2
+
+    define('fib_gen == [1 1 fib]')
+
+.. code:: ipython2
+
+    J('fib_gen 10 [x] times')
+
+
+.. parsed-literal::
+
+    1 2 3 5 8 13 21 34 55 89 [144 89 fib]
+
+
+Project Euler Problem Two
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
+
+Now that we have a generator for the Fibonacci sequence, we need a
+function that adds a term in the sequence to a sum if it is even, and
+``pop``\ s it otherwise.
+
+.. code:: ipython2
+
+    define('PE2.1 == dup 2 % [+] [pop] branch')
+
+And a predicate function that detects when the terms in the series
+"exceed four million".
+
+.. code:: ipython2
+
+    define('>4M == 4000000 >')
+
+Now it's straightforward to define ``PE2`` as a recursive function that
+generates terms in the Fibonacci sequence until they exceed four million
+and sums the even ones.
+
+.. code:: ipython2
+
+    define('PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec')
+
+.. code:: ipython2
+
+    J('PE2')
+
+
+.. parsed-literal::
+
+    4613732
+
+
+Here's the collected program definitions:
+
+::
+
+    fib == + swons [popdd over] infra uncons
+    fib_gen == [1 1 fib]
+
+    even == dup 2 %
+    >4M == 4000000 >
+
+    PE2.1 == even [+] [pop] branch
+    PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
+
+Even-valued Fibonacci Terms
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Using ``o`` for odd and ``e`` for even:
+
+::
+
+    o + o = e
+    e + e = e
+    o + e = o
+
+So the Fibonacci sequence considered in terms of just parity would be:
+
+::
+
+    o o e o o e o o e o o e o o e o o e
+    1 1 2 3 5 8 . . .
+
+Every third term is even.
+
+.. code:: ipython2
+
+    J('[1 0 fib] x x x')  # To start the sequence with 1 1 2 3 instead of 1 2 3.
+
+
+.. parsed-literal::
+
+    1 1 2 [3 2 fib]
+
+
+Drive the generator three times and ``popop`` the two odd terms.
+
+.. code:: ipython2
+
+    J('[1 0 fib] x x x [popop] dipd')
+
+
+.. parsed-literal::
+
+    2 [3 2 fib]
+
+
+.. code:: ipython2
+
+    define('PE2.2 == x x x [popop] dipd')
+
+.. code:: ipython2
+
+    J('[1 0 fib] 10 [PE2.2] times')
+
+
+.. parsed-literal::
+
+    2 8 34 144 610 2584 10946 46368 196418 832040 [1346269 832040 fib]
+
+
+Replace ``x`` with our new driver function ``PE2.2`` and start our
+``fib`` generator at ``1 0``.
+
+.. code:: ipython2
+
+    J('0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec')
+
+
+.. parsed-literal::
+
+    4613732
+
+
+How to compile these?
+=====================
+
+You would probably start with a special version of ``G``, and perhaps
+modifications to the default ``x``?
diff --git a/docs/Hylo-, Ana-, Cata-, and Para-morphisms - Recursion Combinators.rst b/docs/Hylo-, Ana-, Cata-, and Para-morphisms - Recursion Combinators.rst
new file mode 100644 (file)
index 0000000..0fc09f4
--- /dev/null
@@ -0,0 +1,2680 @@
+
+Cf. `"Bananas, Lenses, & Barbed
+Wire" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
+
+`Hylomorphism <https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29>`__
+====================================================================================
+
+A
+`hylomorphism <https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29>`__
+``H :: A -> B`` converts a value of type A into a value of type B by
+means of:
+
+-  A generator ``G :: A -> (A, B)``
+-  A combiner ``F :: (B, B) -> B``
+-  A predicate ``P :: A -> Bool`` to detect the base case
+-  A base case value ``c :: B``
+-  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))
+            return result
+    
+        return H
+
+Finding `Triangular Numbers <https://en.wikipedia.org/wiki/Triangular_number>`__
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As a concrete example let's use a function that, given a positive
+integer, returns the sum of all positive integers less than that one.
+(In this case the types A and B are both ``int``.) ### With ``range()``
+and ``sum()``
+
+.. code:: ipython2
+
+    r = range(10)
+    r
+
+
+
+
+.. parsed-literal::
+
+    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+
+
+.. code:: ipython2
+
+    sum(r)
+
+
+
+
+.. parsed-literal::
+
+    45
+
+
+
+.. code:: ipython2
+
+    range_sum = lambda n: sum(range(n))
+    range_sum(10)
+
+
+
+
+.. parsed-literal::
+
+    45
+
+
+
+As a hylomorphism
+~~~~~~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    G = lambda n: (n - 1, n - 1)
+    F = lambda a, b: a + b
+    P = lambda n: n <= 1
+    
+    H = hylomorphism(0, F, P, G)
+
+.. code:: ipython2
+
+    H(10)
+
+
+
+
+.. parsed-literal::
+
+    45
+
+
+
+If you were to run the above code in a debugger and check out the call
+stack you would find that the variable ``b`` in each call to ``H()`` is
+storing the intermediate values as ``H()`` recurses. This is what was
+meant by "call stack in the form of a cons list".
+
+Joy Preamble
+~~~~~~~~~~~~
+
+.. code:: ipython2
+
+    from notebook_preamble import D, DefinitionWrapper, J, V, define
+
+Hylomorphism in Joy
+-------------------
+
+We can define a combinator ``hylomorphism`` that will make a
+hylomorphism combinator ``H`` from constituent parts.
+
+::
+
+    H == c [F] [P] [G] 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] [pop c] [G] [dip F] genrec
+
+Derivation of ``hylomorphism``
+------------------------------
+
+Now we just need to derive a definition that builds the ``genrec``
+arguments out of the pieces given to the ``hylomorphism`` combinator.
+
+::
+
+    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
+
+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.
+
+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
+
+The order of parameters is different than the one we started with but
+that hardly matters, you can rearrange them or just supply them in the
+expected order.
+
+::
+
+    [P] c [G] [F] hylomorphism == H
+
+.. code:: ipython2
+
+    define('hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec')
+
+Demonstrate summing a range of integers from 0 to n-1.
+
+-  ``[P]`` is ``[0 <=]``
+-  ``c`` is ``0``
+-  ``[G]`` is ``[1 - dup]``
+-  ``[F]`` is ``[+]``
+
+So to sum the positive integers less than five we can do this.
+
+.. code:: ipython2
+
+    V('5 [0 <=] 0 [1 - dup] [+] hylomorphism')
+
+
+.. parsed-literal::
+
+                                                                                   . 5 [0 <=] 0 [1 - dup] [+] hylomorphism
+                                                                                 5 . [0 <=] 0 [1 - dup] [+] hylomorphism
+                                                                          5 [0 <=] . 0 [1 - dup] [+] hylomorphism
+                                                                        5 [0 <=] 0 . [1 - dup] [+] hylomorphism
+                                                              5 [0 <=] 0 [1 - dup] . [+] hylomorphism
+                                                          5 [0 <=] 0 [1 - dup] [+] . hylomorphism
+                                                          5 [0 <=] 0 [1 - dup] [+] . [unit [pop] swoncat] dipd [dip] swoncat genrec
+                                     5 [0 <=] 0 [1 - dup] [+] [unit [pop] swoncat] . dipd [dip] swoncat genrec
+                                                                        5 [0 <=] 0 . unit [pop] swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                        5 [0 <=] 0 . [] cons [pop] swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                     5 [0 <=] 0 [] . cons [pop] swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                      5 [0 <=] [0] . [pop] swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                5 [0 <=] [0] [pop] . swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                5 [0 <=] [0] [pop] . swap concat [1 - dup] [+] [dip] swoncat genrec
+                                                                5 [0 <=] [pop] [0] . concat [1 - dup] [+] [dip] swoncat genrec
+                                                                  5 [0 <=] [pop 0] . [1 - dup] [+] [dip] swoncat genrec
+                                                        5 [0 <=] [pop 0] [1 - dup] . [+] [dip] swoncat genrec
+                                                    5 [0 <=] [pop 0] [1 - dup] [+] . [dip] swoncat genrec
+                                              5 [0 <=] [pop 0] [1 - dup] [+] [dip] . swoncat genrec
+                                              5 [0 <=] [pop 0] [1 - dup] [+] [dip] . swap concat genrec
+                                              5 [0 <=] [pop 0] [1 - dup] [dip] [+] . concat genrec
+                                                5 [0 <=] [pop 0] [1 - dup] [dip +] . genrec
+        5 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte
+    5 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [5] [0 <=] . infra first choice i
+                                                                                 5 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 5] swaack first choice i
+                                                                               5 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 5] swaack first choice i
+                                                                             False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 5] swaack first choice i
+       False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 5] . swaack first choice i
+       5 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i
+         5 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i
+                       5 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i
+                                                                                 5 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +
+                                                                               5 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +
+                                                                                 4 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +
+                                                                               4 4 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +
+                                     4 4 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip +
+                                                                                 4 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 4 +
+                                                                          4 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 4 +
+                                                                  4 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 4 +
+                                                        4 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 4 +
+                                                4 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 4 +
+        4 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 4 +
+    4 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [4] [0 <=] . infra first choice i 4 +
+                                                                                 4 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 4] swaack first choice i 4 +
+                                                                               4 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 4] swaack first choice i 4 +
+                                                                             False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 4] swaack first choice i 4 +
+       False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 4] . swaack first choice i 4 +
+       4 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 4 +
+         4 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 4 +
+                       4 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 4 +
+                                                                                 4 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 4 +
+                                                                               4 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 4 +
+                                                                                 3 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 4 +
+                                                                               3 3 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 4 +
+                                     3 3 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 4 +
+                                                                                 3 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 3 + 4 +
+                                                                          3 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 3 + 4 +
+                                                                  3 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 3 + 4 +
+                                                        3 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 3 + 4 +
+                                                3 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 3 + 4 +
+        3 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 3 + 4 +
+    3 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [3] [0 <=] . infra first choice i 3 + 4 +
+                                                                                 3 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 3] swaack first choice i 3 + 4 +
+                                                                               3 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 3] swaack first choice i 3 + 4 +
+                                                                             False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 3] swaack first choice i 3 + 4 +
+       False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 3] . swaack first choice i 3 + 4 +
+       3 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 3 + 4 +
+         3 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 3 + 4 +
+                       3 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 3 + 4 +
+                                                                                 3 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 3 + 4 +
+                                                                               3 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 3 + 4 +
+                                                                                 2 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 3 + 4 +
+                                                                               2 2 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 3 + 4 +
+                                     2 2 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 3 + 4 +
+                                                                                 2 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 2 + 3 + 4 +
+                                                                          2 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 2 + 3 + 4 +
+                                                                  2 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 2 + 3 + 4 +
+                                                        2 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 2 + 3 + 4 +
+                                                2 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 2 + 3 + 4 +
+        2 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 2 + 3 + 4 +
+    2 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [2] [0 <=] . infra first choice i 2 + 3 + 4 +
+                                                                                 2 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 2] swaack first choice i 2 + 3 + 4 +
+                                                                               2 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 2] swaack first choice i 2 + 3 + 4 +
+                                                                             False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 2] swaack first choice i 2 + 3 + 4 +
+       False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 2] . swaack first choice i 2 + 3 + 4 +
+       2 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 2 + 3 + 4 +
+         2 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 2 + 3 + 4 +
+                       2 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 2 + 3 + 4 +
+                                                                                 2 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 2 + 3 + 4 +
+                                                                               2 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 2 + 3 + 4 +
+                                                                                 1 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 2 + 3 + 4 +
+                                                                               1 1 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 2 + 3 + 4 +
+                                     1 1 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 2 + 3 + 4 +
+                                                                                 1 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 1 + 2 + 3 + 4 +
+                                                                          1 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 1 + 2 + 3 + 4 +
+                                                                  1 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 1 + 2 + 3 + 4 +
+                                                        1 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 1 + 2 + 3 + 4 +
+                                                1 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 1 + 2 + 3 + 4 +
+        1 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 1 + 2 + 3 + 4 +
+    1 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [1] [0 <=] . infra first choice i 1 + 2 + 3 + 4 +
+                                                                                 1 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 1] swaack first choice i 1 + 2 + 3 + 4 +
+                                                                               1 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 1] swaack first choice i 1 + 2 + 3 + 4 +
+                                                                             False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 1] swaack first choice i 1 + 2 + 3 + 4 +
+       False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 1] . swaack first choice i 1 + 2 + 3 + 4 +
+       1 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 1 + 2 + 3 + 4 +
+         1 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 1 + 2 + 3 + 4 +
+                       1 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 1 + 2 + 3 + 4 +
+                                                                                 1 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 1 + 2 + 3 + 4 +
+                                                                               1 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 1 + 2 + 3 + 4 +
+                                                                                 0 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 1 + 2 + 3 + 4 +
+                                                                               0 0 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 1 + 2 + 3 + 4 +
+                                     0 0 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 1 + 2 + 3 + 4 +
+                                                                                 0 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 0 + 1 + 2 + 3 + 4 +
+                                                                          0 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 0 + 1 + 2 + 3 + 4 +
+                                                                  0 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 0 + 1 + 2 + 3 + 4 +
+                                                        0 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 0 + 1 + 2 + 3 + 4 +
+                                                0 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 0 + 1 + 2 + 3 + 4 +
+        0 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 0 + 1 + 2 + 3 + 4 +
+    0 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [0] [0 <=] . infra first choice i 0 + 1 + 2 + 3 + 4 +
+                                                                                 0 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 0] swaack first choice i 0 + 1 + 2 + 3 + 4 +
+                                                                               0 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 0] swaack first choice i 0 + 1 + 2 + 3 + 4 +
+                                                                              True . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 0] swaack first choice i 0 + 1 + 2 + 3 + 4 +
+        True [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 0] . swaack first choice i 0 + 1 + 2 + 3 + 4 +
+        0 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [True] . first choice i 0 + 1 + 2 + 3 + 4 +
+          0 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] True . choice i 0 + 1 + 2 + 3 + 4 +
+                                                                         0 [pop 0] . i 0 + 1 + 2 + 3 + 4 +
+                                                                                 0 . pop 0 0 + 1 + 2 + 3 + 4 +
+                                                                                   . 0 0 + 1 + 2 + 3 + 4 +
+                                                                                 0 . 0 + 1 + 2 + 3 + 4 +
+                                                                               0 0 . + 1 + 2 + 3 + 4 +
+                                                                                 0 . 1 + 2 + 3 + 4 +
+                                                                               0 1 . + 2 + 3 + 4 +
+                                                                                 1 . 2 + 3 + 4 +
+                                                                               1 2 . + 3 + 4 +
+                                                                                 3 . 3 + 4 +
+                                                                               3 3 . + 4 +
+                                                                                 6 . 4 +
+                                                                               6 4 . +
+                                                                                10 . 
+
+
+Anamorphism
+===========
+
+An anamorphism can be defined as a hylomorphism that uses ``[]`` for
+``c`` and ``swons`` for ``F``.
+
+::
+
+    [P] [G] anamorphism == [P] [] [G] [swons] hylomorphism == A
+
+This allows us to define an anamorphism combinator in terms of the
+hylomorphism combinator.
+
+::
+
+    [] swap [swons] hylomorphism == anamorphism
+
+Partial evaluation gives us a "pre-cooked" form.
+
+::
+
+    [P] [G] . anamorphism
+    [P] [G] . [] swap [swons] hylomorphism
+    [P] [G] [] . swap [swons] hylomorphism
+    [P] [] [G] . [swons] hylomorphism
+    [P] [] [G] [swons] . hylomorphism
+    [P] [] [G] [swons] . [unit [pop] swoncat] dipd [dip] swoncat genrec
+    [P] [] [G] [swons] [unit [pop] swoncat] . dipd [dip] swoncat genrec
+    [P] [] . unit [pop] swoncat [G] [swons] [dip] swoncat genrec
+    [P] [[]] [pop] . swoncat [G] [swons] [dip] swoncat genrec
+    [P] [pop []] [G] [swons] [dip] . swoncat genrec
+
+    [P] [pop []] [G] [dip swons] genrec
+
+(We could also have just substituted for ``c`` and ``F`` in the
+definition of ``H``.)
+
+::
+
+    H == [P] [pop c ] [G] [dip F    ] genrec
+    A == [P] [pop []] [G] [dip swons] genrec
+
+The partial evaluation is overkill in this case but it serves as a
+reminder that this sort of program specialization can, in many cases, be
+carried out automatically.)
+
+Untangle ``[G]`` from ``[pop []]`` using ``swap``.
+
+::
+
+    [P] [G] [pop []] swap [dip swons] genrec
+
+All of the arguments to ``anamorphism`` are to the left, so we have a
+definition for it.
+
+::
+
+    anamorphism == [pop []] swap [dip swons] genrec
+
+An example of an anamorphism is the range function.
+
+::
+
+    range == [0 <=] [1 - dup] anamorphism
+
+Catamorphism
+============
+
+A catamorphism can be defined as a hylomorphism that uses
+``[uncons swap]`` for ``[G]`` and ``[[] =]`` for the predicate ``[P]``.
+
+::
+
+    c [F] catamorphism == [[] =] c [uncons swap] [F] hylomorphism == C
+
+This allows us to define a ``catamorphism`` combinator in terms of the
+``hylomorphism`` combinator.
+
+::
+
+    [[] =] roll> [uncons swap] swap hylomorphism == catamorphism
+
+Partial evaluation doesn't help much.
+
+::
+
+    c [F] . catamorphism
+    c [F] . [[] =] roll> [uncons swap] swap hylomorphism
+    c [F] [[] =] . roll> [uncons swap] swap hylomorphism
+    [[] =] c [F] [uncons swap] . swap hylomorphism
+    [[] =] c [uncons swap] [F] . hylomorphism
+    [[] =] c [uncons swap] [F] [unit [pop] swoncat] . dipd [dip] swoncat genrec
+    [[] =] c . unit [pop] swoncat [uncons swap] [F] [dip] swoncat genrec
+    [[] =] [c] [pop] . swoncat [uncons swap] [F] [dip] swoncat genrec
+    [[] =] [pop c] [uncons swap] [F] [dip] . swoncat genrec
+    [[] =] [pop c] [uncons swap] [dip F] genrec
+
+Because the arguments to catamorphism have to be prepared (unlike the
+arguments to anamorphism, which only need to be rearranged slightly)
+there isn't much point to "pre-cooking" the definition.
+
+::
+
+    catamorphism == [[] =] roll> [uncons swap] swap hylomorphism
+
+An example of a catamorphism is the sum function.
+
+::
+
+    sum == 0 [+] catamorphism
+
+"Fusion Law" for catas (UNFINISHED!!!)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+I'm not sure exactly how to translate the "Fusion Law" for catamorphisms
+into Joy.
+
+I know that a ``map`` composed with a cata can be expressed as a new
+cata:
+
+::
+
+    [F] map b [B] cata == b [F B] cata
+
+But this isn't the one described in "Bananas...". That's more like:
+
+A cata composed with some function can be expressed as some other cata:
+
+::
+
+    b [B] catamorphism F == c [C] catamorphism
+
+Given:
+
+::
+
+    b F == c
+
+    ...
+
+    B F == [F] dip C
+
+    ...
+
+    b[B]cata F == c[C]cata
+
+    F(B(head, tail)) == C(head, F(tail))
+
+    1 [2 3] B F         1 [2 3] F C
+
+
+    b F == c
+    B F == F C
+
+    b [B] catamorphism F == c [C] catamorphism
+    b [B] catamorphism F == b F [C] catamorphism
+
+    ...
+
+Or maybe,
+
+::
+
+    [F] map b [B] cata == c [C] cata     ???
+
+    [F] map b [B] cata == b [F B] cata    I think this is generally true, unless F consumes stack items
+                                            instead of just transforming TOS.  Of course, there's always [F] unary.
+    b [F] unary [[F] unary B] cata
+
+    [10 *] map 0 swap [+] step == 0 swap [10 * +] step
+
+For example:
+
+::
+
+    F == 10 *
+    b == 0
+    B == +
+    c == 0
+    C == F +
+
+    b F    == c
+    0 10 * == 0
+
+    B F    == [F]    dip C
+    + 10 * == [10 *] dip F +
+    + 10 * == [10 *] dip 10 * +
+
+    n m + 10 * == 10(n+m)
+
+    n m [10 *] dip 10 * +
+    n 10 * m 10 * +
+    10n m 10 * +
+    10n 10m +
+    10n+10m
+
+    10n+10m = 10(n+m)
+
+Ergo:
+
+::
+
+    0 [+] catamorphism 10 * == 0 [10 * +] catamorphism
+
+The ``step`` combinator will usually be better to use than ``catamorphism``.
+----------------------------------------------------------------------------
+
+::
+
+    sum == 0 swap [+] step
+    sum == 0 [+] catamorphism
+
+anamorphism catamorphism == hylomorphism
+========================================
+
+Here is (part of) the payoff.
+
+An anamorphism followed by (composed with) a catamorphism is a
+hylomorphism, with the advantage that the hylomorphism does not create
+the intermediate list structure. The values are stored in either the
+call stack, for those implementations that use one, or in the pending
+expression ("continuation") for the Joypy interpreter. They still have
+to be somewhere, converting from an anamorphism and catamorphism to a
+hylomorphism just prevents using additional storage and doing additional
+processing.
+
+::
+
+        range == [0 <=] [1 - dup] anamorphism
+          sum == 0 [+] catamorphism
+
+    range sum == [0 <=] [1 - dup] anamorphism 0 [+] catamorphism
+              == [0 <=] 0 [1 - dup] [+] hylomorphism
+
+We can let the ``hylomorphism`` combinator build ``range_sum`` for us or
+just substitute ourselves.
+
+::
+
+            H == [P]    [pop c] [G]       [dip F] genrec
+    range_sum == [0 <=] [pop 0] [1 - dup] [dip +] genrec
+
+.. code:: ipython2
+
+    defs = '''
+    anamorphism == [pop []] swap [dip swons] genrec
+    hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
+    catamorphism == [[] =] roll> [uncons swap] swap hylomorphism
+    range == [0 <=] [1 - dup] anamorphism
+    sum == 0 [+] catamorphism
+    range_sum == [0 <=] 0 [1 - dup] [+] hylomorphism
+    '''
+    
+    DefinitionWrapper.add_definitions(defs, D)
+
+.. code:: ipython2
+
+    J('10 range')
+
+
+.. parsed-literal::
+
+    [9 8 7 6 5 4 3 2 1 0]
+
+
+.. code:: ipython2
+
+    J('[9 8 7 6 5 4 3 2 1 0] sum')
+
+
+.. parsed-literal::
+
+    45
+
+
+.. code:: ipython2
+
+    V('10 range sum')
+
+
+.. parsed-literal::
+
+                                                                                                                                   . 10 range sum
+                                                                                                                                10 . range sum
+                                                                                                                                10 . [0 <=] [1 - dup] anamorphism sum
+                                                                                                                         10 [0 <=] . [1 - dup] anamorphism sum
+                                                                                                               10 [0 <=] [1 - dup] . anamorphism sum
+                                                                                                               10 [0 <=] [1 - dup] . [pop []] swap [dip swons] genrec sum
+                                                                                                      10 [0 <=] [1 - dup] [pop []] . swap [dip swons] genrec sum
+                                                                                                      10 [0 <=] [pop []] [1 - dup] . [dip swons] genrec sum
+                                                                                          10 [0 <=] [pop []] [1 - dup] [dip swons] . genrec sum
+                                             10 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte sum
+                                        10 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [10] [0 <=] . infra first choice i sum
+                                                                                                                                10 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 10] swaack first choice i sum
+                                                                                                                              10 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 10] swaack first choice i sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 10] swaack first choice i sum
+                                            False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 10] . swaack first choice i sum
+                                            10 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i sum
+                                              10 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i sum
+                                                             10 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i sum
+                                                                                                                                10 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons sum
+                                                                                                                              10 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons sum
+                                                                                                                                 9 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons sum
+                                                                                                                               9 9 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons sum
+                                                                                9 9 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons sum
+                                                                                                                                 9 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 9 swons sum
+                                                                                                                          9 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 9 swons sum
+                                                                                                                 9 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 9 swons sum
+                                                                                                       9 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 9 swons sum
+                                                                                           9 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 9 swons sum
+                                              9 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 9 swons sum
+                                          9 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [9] [0 <=] . infra first choice i 9 swons sum
+                                                                                                                                 9 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 9] swaack first choice i 9 swons sum
+                                                                                                                               9 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 9] swaack first choice i 9 swons sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 9] swaack first choice i 9 swons sum
+                                             False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 9] . swaack first choice i 9 swons sum
+                                             9 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 9 swons sum
+                                               9 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i 9 swons sum
+                                                              9 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i 9 swons sum
+                                                                                                                                 9 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 9 swons sum
+                                                                                                                               9 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 9 swons sum
+                                                                                                                                 8 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 9 swons sum
+                                                                                                                               8 8 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 9 swons sum
+                                                                                8 8 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons 9 swons sum
+                                                                                                                                 8 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 8 swons 9 swons sum
+                                                                                                                          8 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 8 swons 9 swons sum
+                                                                                                                 8 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 8 swons 9 swons sum
+                                                                                                       8 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 8 swons 9 swons sum
+                                                                                           8 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 8 swons 9 swons sum
+                                              8 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 8 swons 9 swons sum
+                                          8 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [8] [0 <=] . infra first choice i 8 swons 9 swons sum
+                                                                                                                                 8 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 8] swaack first choice i 8 swons 9 swons sum
+                                                                                                                               8 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 8] swaack first choice i 8 swons 9 swons sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 8] swaack first choice i 8 swons 9 swons sum
+                                             False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 8] . swaack first choice i 8 swons 9 swons sum
+                                             8 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 8 swons 9 swons sum
+                                               8 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i 8 swons 9 swons sum
+                                                              8 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i 8 swons 9 swons sum
+                                                                                                                                 8 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 8 swons 9 swons sum
+                                                                                                                               8 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 8 swons 9 swons sum
+                                                                                                                                 7 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 8 swons 9 swons sum
+                                                                                                                               7 7 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 8 swons 9 swons sum
+                                                                                7 7 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons 8 swons 9 swons sum
+                                                                                                                                 7 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 7 swons 8 swons 9 swons sum
+                                                                                                                          7 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 7 swons 8 swons 9 swons sum
+                                                                                                                 7 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 7 swons 8 swons 9 swons sum
+                                                                                                       7 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 7 swons 8 swons 9 swons sum
+                                                                                           7 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 7 swons 8 swons 9 swons sum
+                                              7 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 7 swons 8 swons 9 swons sum
+                                          7 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [7] [0 <=] . infra first choice i 7 swons 8 swons 9 swons sum
+                                                                                                                                 7 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 7] swaack first choice i 7 swons 8 swons 9 swons sum
+                                                                                                                               7 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 7] swaack first choice i 7 swons 8 swons 9 swons sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 7] swaack first choice i 7 swons 8 swons 9 swons sum
+                                             False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 7] . swaack first choice i 7 swons 8 swons 9 swons sum
+                                             7 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 7 swons 8 swons 9 swons sum
+                                               7 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i 7 swons 8 swons 9 swons sum
+                                                              7 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i 7 swons 8 swons 9 swons sum
+                                                                                                                                 7 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 7 swons 8 swons 9 swons sum
+                                                                                                                               7 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 6 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 7 swons 8 swons 9 swons sum
+                                                                                                                               6 6 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 7 swons 8 swons 9 swons sum
+                                                                                6 6 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 6 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                          6 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                 6 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                       6 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 6 swons 7 swons 8 swons 9 swons sum
+                                                                                           6 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 6 swons 7 swons 8 swons 9 swons sum
+                                              6 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 6 swons 7 swons 8 swons 9 swons sum
+                                          6 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [6] [0 <=] . infra first choice i 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 6 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 6] swaack first choice i 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               6 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 6] swaack first choice i 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 6] swaack first choice i 6 swons 7 swons 8 swons 9 swons sum
+                                             False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 6] . swaack first choice i 6 swons 7 swons 8 swons 9 swons sum
+                                             6 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 6 swons 7 swons 8 swons 9 swons sum
+                                               6 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i 6 swons 7 swons 8 swons 9 swons sum
+                                                              6 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 6 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               6 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 5 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               5 5 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                5 5 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 5 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                          5 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                 5 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                       5 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                           5 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                              5 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                          5 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [5] [0 <=] . infra first choice i 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 5 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 5] swaack first choice i 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               5 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 5] swaack first choice i 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 5] swaack first choice i 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 5] . swaack first choice i 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             5 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                               5 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                              5 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 5 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               5 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 4 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               4 4 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                4 4 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 4 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                          4 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                 4 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                       4 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                           4 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                              4 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                          4 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [4] [0 <=] . infra first choice i 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 4 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 4] swaack first choice i 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               4 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 4] swaack first choice i 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 4] swaack first choice i 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 4] . swaack first choice i 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             4 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                               4 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                              4 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 4 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               4 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 3 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               3 3 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                3 3 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 3 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                          3 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                 3 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                       3 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                           3 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                              3 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                          3 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [3] [0 <=] . infra first choice i 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 3 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 3] swaack first choice i 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               3 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 3] swaack first choice i 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 3] swaack first choice i 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 3] . swaack first choice i 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             3 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                               3 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                              3 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 3 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               3 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 2 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               2 2 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                2 2 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 2 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                          2 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                 2 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                       2 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                           2 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                              2 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                          2 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [2] [0 <=] . infra first choice i 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 2 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 2] swaack first choice i 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               2 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 2] swaack first choice i 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 2] swaack first choice i 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 2] . swaack first choice i 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             2 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                               2 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                              2 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 2 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               2 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 1 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               1 1 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                1 1 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 1 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                          1 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                 1 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                       1 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                           1 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                              1 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                          1 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [1] [0 <=] . infra first choice i 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 1 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 1] swaack first choice i 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               1 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 1] swaack first choice i 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             False . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 1] swaack first choice i 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             False [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 1] . swaack first choice i 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                             1 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                               1 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] False . choice i 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                              1 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . i 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 1 . 1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               1 1 . - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 0 . dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               0 0 . [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                0 0 [[0 <=] [pop []] [1 - dup] [dip swons] genrec] . dip swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 0 . [0 <=] [pop []] [1 - dup] [dip swons] genrec 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                          0 [0 <=] . [pop []] [1 - dup] [dip swons] genrec 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                 0 [0 <=] [pop []] . [1 - dup] [dip swons] genrec 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                       0 [0 <=] [pop []] [1 - dup] . [dip swons] genrec 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                           0 [0 <=] [pop []] [1 - dup] [dip swons] . genrec 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                              0 [0 <=] [pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] . ifte 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                          0 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [0] [0 <=] . infra first choice i 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 0 . 0 <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 0] swaack first choice i 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               0 0 . <= [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 0] swaack first choice i 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                              True . [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 0] swaack first choice i 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                              True [[pop []] [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] 0] . swaack first choice i 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                              0 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] [True] . first choice i 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                0 [1 - dup [[0 <=] [pop []] [1 - dup] [dip swons] genrec] dip swons] [pop []] True . choice i 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                        0 [pop []] . i 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                 0 . pop [] 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                   . [] 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                                [] . 0 swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                              [] 0 . swons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                              [] 0 . swap cons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                              0 [] . cons 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                               [0] . 1 swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             [0] 1 . swons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             [0] 1 . swap cons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             1 [0] . cons 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                             [1 0] . 2 swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                           [1 0] 2 . swons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                           [1 0] 2 . swap cons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                           2 [1 0] . cons 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                           [2 1 0] . 3 swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                         [2 1 0] 3 . swons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                         [2 1 0] 3 . swap cons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                         3 [2 1 0] . cons 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                         [3 2 1 0] . 4 swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                       [3 2 1 0] 4 . swons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                       [3 2 1 0] 4 . swap cons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                       4 [3 2 1 0] . cons 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                       [4 3 2 1 0] . 5 swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                     [4 3 2 1 0] 5 . swons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                     [4 3 2 1 0] 5 . swap cons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                     5 [4 3 2 1 0] . cons 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                     [5 4 3 2 1 0] . 6 swons 7 swons 8 swons 9 swons sum
+                                                                                                                   [5 4 3 2 1 0] 6 . swons 7 swons 8 swons 9 swons sum
+                                                                                                                   [5 4 3 2 1 0] 6 . swap cons 7 swons 8 swons 9 swons sum
+                                                                                                                   6 [5 4 3 2 1 0] . cons 7 swons 8 swons 9 swons sum
+                                                                                                                   [6 5 4 3 2 1 0] . 7 swons 8 swons 9 swons sum
+                                                                                                                 [6 5 4 3 2 1 0] 7 . swons 8 swons 9 swons sum
+                                                                                                                 [6 5 4 3 2 1 0] 7 . swap cons 8 swons 9 swons sum
+                                                                                                                 7 [6 5 4 3 2 1 0] . cons 8 swons 9 swons sum
+                                                                                                                 [7 6 5 4 3 2 1 0] . 8 swons 9 swons sum
+                                                                                                               [7 6 5 4 3 2 1 0] 8 . swons 9 swons sum
+                                                                                                               [7 6 5 4 3 2 1 0] 8 . swap cons 9 swons sum
+                                                                                                               8 [7 6 5 4 3 2 1 0] . cons 9 swons sum
+                                                                                                               [8 7 6 5 4 3 2 1 0] . 9 swons sum
+                                                                                                             [8 7 6 5 4 3 2 1 0] 9 . swons sum
+                                                                                                             [8 7 6 5 4 3 2 1 0] 9 . swap cons sum
+                                                                                                             9 [8 7 6 5 4 3 2 1 0] . cons sum
+                                                                                                             [9 8 7 6 5 4 3 2 1 0] . sum
+                                                                                                             [9 8 7 6 5 4 3 2 1 0] . 0 [+] catamorphism
+                                                                                                           [9 8 7 6 5 4 3 2 1 0] 0 . [+] catamorphism
+                                                                                                       [9 8 7 6 5 4 3 2 1 0] 0 [+] . catamorphism
+                                                                                                       [9 8 7 6 5 4 3 2 1 0] 0 [+] . [[] =] roll> [uncons swap] swap hylomorphism
+                                                                                                [9 8 7 6 5 4 3 2 1 0] 0 [+] [[] =] . roll> [uncons swap] swap hylomorphism
+                                                                                                [9 8 7 6 5 4 3 2 1 0] [[] =] 0 [+] . [uncons swap] swap hylomorphism
+                                                                                  [9 8 7 6 5 4 3 2 1 0] [[] =] 0 [+] [uncons swap] . swap hylomorphism
+                                                                                  [9 8 7 6 5 4 3 2 1 0] [[] =] 0 [uncons swap] [+] . hylomorphism
+                                                                                  [9 8 7 6 5 4 3 2 1 0] [[] =] 0 [uncons swap] [+] . [unit [pop] swoncat] dipd [dip] swoncat genrec
+                                                             [9 8 7 6 5 4 3 2 1 0] [[] =] 0 [uncons swap] [+] [unit [pop] swoncat] . dipd [dip] swoncat genrec
+                                                                                                    [9 8 7 6 5 4 3 2 1 0] [[] =] 0 . unit [pop] swoncat [uncons swap] [+] [dip] swoncat genrec
+                                                                                                    [9 8 7 6 5 4 3 2 1 0] [[] =] 0 . [] cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec
+                                                                                                 [9 8 7 6 5 4 3 2 1 0] [[] =] 0 [] . cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec
+                                                                                                  [9 8 7 6 5 4 3 2 1 0] [[] =] [0] . [pop] swoncat [uncons swap] [+] [dip] swoncat genrec
+                                                                                            [9 8 7 6 5 4 3 2 1 0] [[] =] [0] [pop] . swoncat [uncons swap] [+] [dip] swoncat genrec
+                                                                                            [9 8 7 6 5 4 3 2 1 0] [[] =] [0] [pop] . swap concat [uncons swap] [+] [dip] swoncat genrec
+                                                                                            [9 8 7 6 5 4 3 2 1 0] [[] =] [pop] [0] . concat [uncons swap] [+] [dip] swoncat genrec
+                                                                                              [9 8 7 6 5 4 3 2 1 0] [[] =] [pop 0] . [uncons swap] [+] [dip] swoncat genrec
+                                                                                [9 8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] . [+] [dip] swoncat genrec
+                                                                            [9 8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] [+] . [dip] swoncat genrec
+                                                                      [9 8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] [+] [dip] . swoncat genrec
+                                                                      [9 8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] [+] [dip] . swap concat genrec
+                                                                      [9 8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] [dip] [+] . concat genrec
+                                                                        [9 8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] [dip +] . genrec
+                            [9 8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte
+    [9 8 7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[9 8 7 6 5 4 3 2 1 0]] [[] =] . infra first choice i
+                                                                                                             [9 8 7 6 5 4 3 2 1 0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [9 8 7 6 5 4 3 2 1 0]] swaack first choice i
+                                                                                                          [9 8 7 6 5 4 3 2 1 0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [9 8 7 6 5 4 3 2 1 0]] swaack first choice i
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [9 8 7 6 5 4 3 2 1 0]] swaack first choice i
+                           False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [9 8 7 6 5 4 3 2 1 0]] . swaack first choice i
+                           [9 8 7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i
+                             [9 8 7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i
+                                           [9 8 7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i
+                                                                                                             [9 8 7 6 5 4 3 2 1 0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +
+                                                                                                             9 [8 7 6 5 4 3 2 1 0] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +
+                                                                                                             [8 7 6 5 4 3 2 1 0] 9 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +
+                                                               [8 7 6 5 4 3 2 1 0] 9 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip +
+                                                                                                               [8 7 6 5 4 3 2 1 0] . [[] =] [pop 0] [uncons swap] [dip +] genrec 9 +
+                                                                                                        [8 7 6 5 4 3 2 1 0] [[] =] . [pop 0] [uncons swap] [dip +] genrec 9 +
+                                                                                                [8 7 6 5 4 3 2 1 0] [[] =] [pop 0] . [uncons swap] [dip +] genrec 9 +
+                                                                                  [8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] . [dip +] genrec 9 +
+                                                                          [8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] [dip +] . genrec 9 +
+                              [8 7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 9 +
+        [8 7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[8 7 6 5 4 3 2 1 0]] [[] =] . infra first choice i 9 +
+                                                                                                               [8 7 6 5 4 3 2 1 0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [8 7 6 5 4 3 2 1 0]] swaack first choice i 9 +
+                                                                                                            [8 7 6 5 4 3 2 1 0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [8 7 6 5 4 3 2 1 0]] swaack first choice i 9 +
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [8 7 6 5 4 3 2 1 0]] swaack first choice i 9 +
+                             False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [8 7 6 5 4 3 2 1 0]] . swaack first choice i 9 +
+                             [8 7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i 9 +
+                               [8 7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 9 +
+                                             [8 7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 9 +
+                                                                                                               [8 7 6 5 4 3 2 1 0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 9 +
+                                                                                                               8 [7 6 5 4 3 2 1 0] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 9 +
+                                                                                                               [7 6 5 4 3 2 1 0] 8 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 9 +
+                                                                 [7 6 5 4 3 2 1 0] 8 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 9 +
+                                                                                                                 [7 6 5 4 3 2 1 0] . [[] =] [pop 0] [uncons swap] [dip +] genrec 8 + 9 +
+                                                                                                          [7 6 5 4 3 2 1 0] [[] =] . [pop 0] [uncons swap] [dip +] genrec 8 + 9 +
+                                                                                                  [7 6 5 4 3 2 1 0] [[] =] [pop 0] . [uncons swap] [dip +] genrec 8 + 9 +
+                                                                                    [7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] . [dip +] genrec 8 + 9 +
+                                                                            [7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] [dip +] . genrec 8 + 9 +
+                                [7 6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 8 + 9 +
+            [7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[7 6 5 4 3 2 1 0]] [[] =] . infra first choice i 8 + 9 +
+                                                                                                                 [7 6 5 4 3 2 1 0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [7 6 5 4 3 2 1 0]] swaack first choice i 8 + 9 +
+                                                                                                              [7 6 5 4 3 2 1 0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [7 6 5 4 3 2 1 0]] swaack first choice i 8 + 9 +
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [7 6 5 4 3 2 1 0]] swaack first choice i 8 + 9 +
+                               False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [7 6 5 4 3 2 1 0]] . swaack first choice i 8 + 9 +
+                               [7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i 8 + 9 +
+                                 [7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 8 + 9 +
+                                               [7 6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 8 + 9 +
+                                                                                                                 [7 6 5 4 3 2 1 0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 8 + 9 +
+                                                                                                                 7 [6 5 4 3 2 1 0] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 8 + 9 +
+                                                                                                                 [6 5 4 3 2 1 0] 7 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 8 + 9 +
+                                                                   [6 5 4 3 2 1 0] 7 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 8 + 9 +
+                                                                                                                   [6 5 4 3 2 1 0] . [[] =] [pop 0] [uncons swap] [dip +] genrec 7 + 8 + 9 +
+                                                                                                            [6 5 4 3 2 1 0] [[] =] . [pop 0] [uncons swap] [dip +] genrec 7 + 8 + 9 +
+                                                                                                    [6 5 4 3 2 1 0] [[] =] [pop 0] . [uncons swap] [dip +] genrec 7 + 8 + 9 +
+                                                                                      [6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] . [dip +] genrec 7 + 8 + 9 +
+                                                                              [6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] [dip +] . genrec 7 + 8 + 9 +
+                                  [6 5 4 3 2 1 0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 7 + 8 + 9 +
+                [6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[6 5 4 3 2 1 0]] [[] =] . infra first choice i 7 + 8 + 9 +
+                                                                                                                   [6 5 4 3 2 1 0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [6 5 4 3 2 1 0]] swaack first choice i 7 + 8 + 9 +
+                                                                                                                [6 5 4 3 2 1 0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [6 5 4 3 2 1 0]] swaack first choice i 7 + 8 + 9 +
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [6 5 4 3 2 1 0]] swaack first choice i 7 + 8 + 9 +
+                                 False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [6 5 4 3 2 1 0]] . swaack first choice i 7 + 8 + 9 +
+                                 [6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i 7 + 8 + 9 +
+                                   [6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 7 + 8 + 9 +
+                                                 [6 5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 7 + 8 + 9 +
+                                                                                                                   [6 5 4 3 2 1 0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 7 + 8 + 9 +
+                                                                                                                   6 [5 4 3 2 1 0] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 7 + 8 + 9 +
+                                                                                                                   [5 4 3 2 1 0] 6 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 7 + 8 + 9 +
+                                                                     [5 4 3 2 1 0] 6 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 7 + 8 + 9 +
+                                                                                                                     [5 4 3 2 1 0] . [[] =] [pop 0] [uncons swap] [dip +] genrec 6 + 7 + 8 + 9 +
+                                                                                                              [5 4 3 2 1 0] [[] =] . [pop 0] [uncons swap] [dip +] genrec 6 + 7 + 8 + 9 +
+                                                                                                      [5 4 3 2 1 0] [[] =] [pop 0] . [uncons swap] [dip +] genrec 6 + 7 + 8 + 9 +
+                                                                                        [5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] . [dip +] genrec 6 + 7 + 8 + 9 +
+                                                                                [5 4 3 2 1 0] [[] =] [pop 0] [uncons swap] [dip +] . genrec 6 + 7 + 8 + 9 +
+                                    [5 4 3 2 1 0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 6 + 7 + 8 + 9 +
+                    [5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[5 4 3 2 1 0]] [[] =] . infra first choice i 6 + 7 + 8 + 9 +
+                                                                                                                     [5 4 3 2 1 0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [5 4 3 2 1 0]] swaack first choice i 6 + 7 + 8 + 9 +
+                                                                                                                  [5 4 3 2 1 0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [5 4 3 2 1 0]] swaack first choice i 6 + 7 + 8 + 9 +
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [5 4 3 2 1 0]] swaack first choice i 6 + 7 + 8 + 9 +
+                                   False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [5 4 3 2 1 0]] . swaack first choice i 6 + 7 + 8 + 9 +
+                                   [5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i 6 + 7 + 8 + 9 +
+                                     [5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 6 + 7 + 8 + 9 +
+                                                   [5 4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 6 + 7 + 8 + 9 +
+                                                                                                                     [5 4 3 2 1 0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 6 + 7 + 8 + 9 +
+                                                                                                                     5 [4 3 2 1 0] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 6 + 7 + 8 + 9 +
+                                                                                                                     [4 3 2 1 0] 5 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 6 + 7 + 8 + 9 +
+                                                                       [4 3 2 1 0] 5 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 6 + 7 + 8 + 9 +
+                                                                                                                       [4 3 2 1 0] . [[] =] [pop 0] [uncons swap] [dip +] genrec 5 + 6 + 7 + 8 + 9 +
+                                                                                                                [4 3 2 1 0] [[] =] . [pop 0] [uncons swap] [dip +] genrec 5 + 6 + 7 + 8 + 9 +
+                                                                                                        [4 3 2 1 0] [[] =] [pop 0] . [uncons swap] [dip +] genrec 5 + 6 + 7 + 8 + 9 +
+                                                                                          [4 3 2 1 0] [[] =] [pop 0] [uncons swap] . [dip +] genrec 5 + 6 + 7 + 8 + 9 +
+                                                                                  [4 3 2 1 0] [[] =] [pop 0] [uncons swap] [dip +] . genrec 5 + 6 + 7 + 8 + 9 +
+                                      [4 3 2 1 0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 5 + 6 + 7 + 8 + 9 +
+                        [4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[4 3 2 1 0]] [[] =] . infra first choice i 5 + 6 + 7 + 8 + 9 +
+                                                                                                                       [4 3 2 1 0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [4 3 2 1 0]] swaack first choice i 5 + 6 + 7 + 8 + 9 +
+                                                                                                                    [4 3 2 1 0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [4 3 2 1 0]] swaack first choice i 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [4 3 2 1 0]] swaack first choice i 5 + 6 + 7 + 8 + 9 +
+                                     False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [4 3 2 1 0]] . swaack first choice i 5 + 6 + 7 + 8 + 9 +
+                                     [4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i 5 + 6 + 7 + 8 + 9 +
+                                       [4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 5 + 6 + 7 + 8 + 9 +
+                                                     [4 3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 5 + 6 + 7 + 8 + 9 +
+                                                                                                                       [4 3 2 1 0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                       4 [3 2 1 0] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                       [3 2 1 0] 4 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 5 + 6 + 7 + 8 + 9 +
+                                                                         [3 2 1 0] 4 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                         [3 2 1 0] . [[] =] [pop 0] [uncons swap] [dip +] genrec 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                  [3 2 1 0] [[] =] . [pop 0] [uncons swap] [dip +] genrec 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                          [3 2 1 0] [[] =] [pop 0] . [uncons swap] [dip +] genrec 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                            [3 2 1 0] [[] =] [pop 0] [uncons swap] . [dip +] genrec 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                    [3 2 1 0] [[] =] [pop 0] [uncons swap] [dip +] . genrec 4 + 5 + 6 + 7 + 8 + 9 +
+                                        [3 2 1 0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 4 + 5 + 6 + 7 + 8 + 9 +
+                            [3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[3 2 1 0]] [[] =] . infra first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                         [3 2 1 0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [3 2 1 0]] swaack first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                      [3 2 1 0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [3 2 1 0]] swaack first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [3 2 1 0]] swaack first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                       False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [3 2 1 0]] . swaack first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                       [3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                         [3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                                       [3 2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                         [3 2 1 0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                         3 [2 1 0] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                         [2 1 0] 3 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                           [2 1 0] 3 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                           [2 1 0] . [[] =] [pop 0] [uncons swap] [dip +] genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                    [2 1 0] [[] =] . [pop 0] [uncons swap] [dip +] genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                            [2 1 0] [[] =] [pop 0] . [uncons swap] [dip +] genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                              [2 1 0] [[] =] [pop 0] [uncons swap] . [dip +] genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                      [2 1 0] [[] =] [pop 0] [uncons swap] [dip +] . genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                          [2 1 0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                [2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[2 1 0]] [[] =] . infra first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                           [2 1 0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [2 1 0]] swaack first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                        [2 1 0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [2 1 0]] swaack first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [2 1 0]] swaack first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                         False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [2 1 0]] . swaack first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                         [2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                           [2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                         [2 1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                           [2 1 0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                           2 [1 0] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                           [1 0] 2 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                             [1 0] 2 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             [1 0] . [[] =] [pop 0] [uncons swap] [dip +] genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                      [1 0] [[] =] . [pop 0] [uncons swap] [dip +] genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                              [1 0] [[] =] [pop 0] . [uncons swap] [dip +] genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                [1 0] [[] =] [pop 0] [uncons swap] . [dip +] genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                        [1 0] [[] =] [pop 0] [uncons swap] [dip +] . genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                            [1 0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                    [1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[1 0]] [[] =] . infra first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             [1 0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [1 0]] swaack first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                          [1 0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [1 0]] swaack first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [1 0]] swaack first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                           False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [1 0]] . swaack first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                           [1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                             [1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                           [1 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             [1 0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             1 [0] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             [0] 1 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                               [0] 1 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                               [0] . [[] =] [pop 0] [uncons swap] [dip +] genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                        [0] [[] =] . [pop 0] [uncons swap] [dip +] genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                [0] [[] =] [pop 0] . [uncons swap] [dip +] genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                  [0] [[] =] [pop 0] [uncons swap] . [dip +] genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                          [0] [[] =] [pop 0] [uncons swap] [dip +] . genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                              [0] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                        [0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[0]] [[] =] . infra first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                               [0] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [0]] swaack first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                            [0] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [0]] swaack first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [0]] swaack first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                             False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [0]] . swaack first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                             [0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False] . first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                               [0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                             [0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                               [0] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                              0 [] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                              [] 0 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                [] 0 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                [] . [[] =] [pop 0] [uncons swap] [dip +] genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                         [] [[] =] . [pop 0] [uncons swap] [dip +] genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                 [] [[] =] [pop 0] . [uncons swap] [dip +] genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                   [] [[] =] [pop 0] [uncons swap] . [dip +] genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                           [] [[] =] [pop 0] [uncons swap] [dip +] . genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                               [] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                          [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[]] [[] =] . infra first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                [] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] []] swaack first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                             [] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] []] swaack first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                              True . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] []] swaack first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                               True [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] []] . swaack first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                               [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [True] . first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] True . choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                        [] [pop 0] . i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                [] . pop 0 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                   . 0 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                 0 . 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                               0 0 . + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                 0 . 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                               0 1 . + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                 1 . 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                               1 2 . + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                 3 . 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                               3 3 . + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                 6 . 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                               6 4 . + 5 + 6 + 7 + 8 + 9 +
+                                                                                                                                10 . 5 + 6 + 7 + 8 + 9 +
+                                                                                                                              10 5 . + 6 + 7 + 8 + 9 +
+                                                                                                                                15 . 6 + 7 + 8 + 9 +
+                                                                                                                              15 6 . + 7 + 8 + 9 +
+                                                                                                                                21 . 7 + 8 + 9 +
+                                                                                                                              21 7 . + 8 + 9 +
+                                                                                                                                28 . 8 + 9 +
+                                                                                                                              28 8 . + 9 +
+                                                                                                                                36 . 9 +
+                                                                                                                              36 9 . +
+                                                                                                                                45 . 
+
+
+.. code:: ipython2
+
+    V('10 range_sum')
+
+
+.. parsed-literal::
+
+                                                                                     . 10 range_sum
+                                                                                  10 . range_sum
+                                                                                  10 . [0 <=] 0 [1 - dup] [+] hylomorphism
+                                                                           10 [0 <=] . 0 [1 - dup] [+] hylomorphism
+                                                                         10 [0 <=] 0 . [1 - dup] [+] hylomorphism
+                                                               10 [0 <=] 0 [1 - dup] . [+] hylomorphism
+                                                           10 [0 <=] 0 [1 - dup] [+] . hylomorphism
+                                                           10 [0 <=] 0 [1 - dup] [+] . [unit [pop] swoncat] dipd [dip] swoncat genrec
+                                      10 [0 <=] 0 [1 - dup] [+] [unit [pop] swoncat] . dipd [dip] swoncat genrec
+                                                                         10 [0 <=] 0 . unit [pop] swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                         10 [0 <=] 0 . [] cons [pop] swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                      10 [0 <=] 0 [] . cons [pop] swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                       10 [0 <=] [0] . [pop] swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                 10 [0 <=] [0] [pop] . swoncat [1 - dup] [+] [dip] swoncat genrec
+                                                                 10 [0 <=] [0] [pop] . swap concat [1 - dup] [+] [dip] swoncat genrec
+                                                                 10 [0 <=] [pop] [0] . concat [1 - dup] [+] [dip] swoncat genrec
+                                                                   10 [0 <=] [pop 0] . [1 - dup] [+] [dip] swoncat genrec
+                                                         10 [0 <=] [pop 0] [1 - dup] . [+] [dip] swoncat genrec
+                                                     10 [0 <=] [pop 0] [1 - dup] [+] . [dip] swoncat genrec
+                                               10 [0 <=] [pop 0] [1 - dup] [+] [dip] . swoncat genrec
+                                               10 [0 <=] [pop 0] [1 - dup] [+] [dip] . swap concat genrec
+                                               10 [0 <=] [pop 0] [1 - dup] [dip] [+] . concat genrec
+                                                 10 [0 <=] [pop 0] [1 - dup] [dip +] . genrec
+         10 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte
+    10 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [10] [0 <=] . infra first choice i
+                                                                                  10 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 10] swaack first choice i
+                                                                                10 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 10] swaack first choice i
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 10] swaack first choice i
+        False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 10] . swaack first choice i
+        10 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i
+          10 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i
+                        10 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i
+                                                                                  10 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +
+                                                                                10 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +
+                                                                                   9 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +
+                                                                                 9 9 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +
+                                       9 9 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip +
+                                                                                   9 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 9 +
+                                                                            9 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 9 +
+                                                                    9 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 9 +
+                                                          9 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 9 +
+                                                  9 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 9 +
+          9 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 9 +
+      9 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [9] [0 <=] . infra first choice i 9 +
+                                                                                   9 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 9] swaack first choice i 9 +
+                                                                                 9 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 9] swaack first choice i 9 +
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 9] swaack first choice i 9 +
+         False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 9] . swaack first choice i 9 +
+         9 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 9 +
+           9 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 9 +
+                         9 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 9 +
+                                                                                   9 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 9 +
+                                                                                 9 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 9 +
+                                                                                   8 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 9 +
+                                                                                 8 8 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 9 +
+                                       8 8 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 9 +
+                                                                                   8 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 8 + 9 +
+                                                                            8 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 8 + 9 +
+                                                                    8 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 8 + 9 +
+                                                          8 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 8 + 9 +
+                                                  8 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 8 + 9 +
+          8 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 8 + 9 +
+      8 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [8] [0 <=] . infra first choice i 8 + 9 +
+                                                                                   8 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 8] swaack first choice i 8 + 9 +
+                                                                                 8 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 8] swaack first choice i 8 + 9 +
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 8] swaack first choice i 8 + 9 +
+         False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 8] . swaack first choice i 8 + 9 +
+         8 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 8 + 9 +
+           8 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 8 + 9 +
+                         8 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 8 + 9 +
+                                                                                   8 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 8 + 9 +
+                                                                                 8 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 8 + 9 +
+                                                                                   7 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 8 + 9 +
+                                                                                 7 7 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 8 + 9 +
+                                       7 7 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 8 + 9 +
+                                                                                   7 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 7 + 8 + 9 +
+                                                                            7 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 7 + 8 + 9 +
+                                                                    7 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 7 + 8 + 9 +
+                                                          7 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 7 + 8 + 9 +
+                                                  7 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 7 + 8 + 9 +
+          7 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 7 + 8 + 9 +
+      7 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [7] [0 <=] . infra first choice i 7 + 8 + 9 +
+                                                                                   7 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 7] swaack first choice i 7 + 8 + 9 +
+                                                                                 7 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 7] swaack first choice i 7 + 8 + 9 +
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 7] swaack first choice i 7 + 8 + 9 +
+         False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 7] . swaack first choice i 7 + 8 + 9 +
+         7 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 7 + 8 + 9 +
+           7 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 7 + 8 + 9 +
+                         7 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 7 + 8 + 9 +
+                                                                                   7 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 7 + 8 + 9 +
+                                                                                 7 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 7 + 8 + 9 +
+                                                                                   6 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 7 + 8 + 9 +
+                                                                                 6 6 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 7 + 8 + 9 +
+                                       6 6 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 7 + 8 + 9 +
+                                                                                   6 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 6 + 7 + 8 + 9 +
+                                                                            6 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 6 + 7 + 8 + 9 +
+                                                                    6 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 6 + 7 + 8 + 9 +
+                                                          6 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 6 + 7 + 8 + 9 +
+                                                  6 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 6 + 7 + 8 + 9 +
+          6 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 6 + 7 + 8 + 9 +
+      6 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [6] [0 <=] . infra first choice i 6 + 7 + 8 + 9 +
+                                                                                   6 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 6] swaack first choice i 6 + 7 + 8 + 9 +
+                                                                                 6 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 6] swaack first choice i 6 + 7 + 8 + 9 +
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 6] swaack first choice i 6 + 7 + 8 + 9 +
+         False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 6] . swaack first choice i 6 + 7 + 8 + 9 +
+         6 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 6 + 7 + 8 + 9 +
+           6 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 6 + 7 + 8 + 9 +
+                         6 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 6 + 7 + 8 + 9 +
+                                                                                   6 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 6 + 7 + 8 + 9 +
+                                                                                 6 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 6 + 7 + 8 + 9 +
+                                                                                   5 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 6 + 7 + 8 + 9 +
+                                                                                 5 5 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 6 + 7 + 8 + 9 +
+                                       5 5 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 6 + 7 + 8 + 9 +
+                                                                                   5 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 5 + 6 + 7 + 8 + 9 +
+                                                                            5 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 5 + 6 + 7 + 8 + 9 +
+                                                                    5 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 5 + 6 + 7 + 8 + 9 +
+                                                          5 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 5 + 6 + 7 + 8 + 9 +
+                                                  5 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 5 + 6 + 7 + 8 + 9 +
+          5 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 5 + 6 + 7 + 8 + 9 +
+      5 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [5] [0 <=] . infra first choice i 5 + 6 + 7 + 8 + 9 +
+                                                                                   5 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 5] swaack first choice i 5 + 6 + 7 + 8 + 9 +
+                                                                                 5 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 5] swaack first choice i 5 + 6 + 7 + 8 + 9 +
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 5] swaack first choice i 5 + 6 + 7 + 8 + 9 +
+         False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 5] . swaack first choice i 5 + 6 + 7 + 8 + 9 +
+         5 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 5 + 6 + 7 + 8 + 9 +
+           5 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 5 + 6 + 7 + 8 + 9 +
+                         5 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 5 + 6 + 7 + 8 + 9 +
+                                                                                   5 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 5 + 6 + 7 + 8 + 9 +
+                                                                                 5 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 5 + 6 + 7 + 8 + 9 +
+                                                                                   4 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 5 + 6 + 7 + 8 + 9 +
+                                                                                 4 4 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 5 + 6 + 7 + 8 + 9 +
+                                       4 4 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 5 + 6 + 7 + 8 + 9 +
+                                                                                   4 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                            4 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                    4 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 4 + 5 + 6 + 7 + 8 + 9 +
+                                                          4 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 4 + 5 + 6 + 7 + 8 + 9 +
+                                                  4 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 4 + 5 + 6 + 7 + 8 + 9 +
+          4 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 4 + 5 + 6 + 7 + 8 + 9 +
+      4 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [4] [0 <=] . infra first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   4 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 4] swaack first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 4 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 4] swaack first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 4] swaack first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+         False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 4] . swaack first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+         4 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 4 + 5 + 6 + 7 + 8 + 9 +
+           4 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 4 + 5 + 6 + 7 + 8 + 9 +
+                         4 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   4 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 4 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   3 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 3 3 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 4 + 5 + 6 + 7 + 8 + 9 +
+                                       3 3 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   3 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                            3 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                    3 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                          3 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                  3 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+          3 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+      3 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [3] [0 <=] . infra first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   3 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 3] swaack first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 3 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 3] swaack first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 3] swaack first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+         False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 3] . swaack first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+         3 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+           3 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                         3 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   3 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 3 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   2 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 2 2 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                       2 2 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   2 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                            2 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                    2 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                          2 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                  2 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+          2 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+      2 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [2] [0 <=] . infra first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   2 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 2] swaack first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 2 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 2] swaack first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 2] swaack first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+         False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 2] . swaack first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+         2 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+           2 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                         2 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   2 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 2 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   1 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 1 1 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                       1 1 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   1 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                            1 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                    1 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                          1 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                  1 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+          1 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+      1 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [1] [0 <=] . infra first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   1 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 1] swaack first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 1 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 1] swaack first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                               False . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 1] swaack first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+         False [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 1] . swaack first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+         1 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [False] . first choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+           1 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] False . choice i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                         1 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . i 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   1 . 1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 1 1 . - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   0 . dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 0 0 . [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                       0 0 [[0 <=] [pop 0] [1 - dup] [dip +] genrec] . dip + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   0 . [0 <=] [pop 0] [1 - dup] [dip +] genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                            0 [0 <=] . [pop 0] [1 - dup] [dip +] genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                    0 [0 <=] [pop 0] . [1 - dup] [dip +] genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                          0 [0 <=] [pop 0] [1 - dup] . [dip +] genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                  0 [0 <=] [pop 0] [1 - dup] [dip +] . genrec 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+          0 [0 <=] [pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] . ifte 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+      0 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [0] [0 <=] . infra first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   0 . 0 <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 0] swaack first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 0 0 . <= [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 0] swaack first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                True . [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 0] swaack first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+          True [[pop 0] [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] 0] . swaack first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+          0 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] [True] . first choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+            0 [1 - dup [[0 <=] [pop 0] [1 - dup] [dip +] genrec] dip +] [pop 0] True . choice i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                           0 [pop 0] . i 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   0 . pop 0 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                     . 0 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   0 . 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 0 0 . + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   0 . 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 0 1 . + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   1 . 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 1 2 . + 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   3 . 3 + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 3 3 . + 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                   6 . 4 + 5 + 6 + 7 + 8 + 9 +
+                                                                                 6 4 . + 5 + 6 + 7 + 8 + 9 +
+                                                                                  10 . 5 + 6 + 7 + 8 + 9 +
+                                                                                10 5 . + 6 + 7 + 8 + 9 +
+                                                                                  15 . 6 + 7 + 8 + 9 +
+                                                                                15 6 . + 7 + 8 + 9 +
+                                                                                  21 . 7 + 8 + 9 +
+                                                                                21 7 . + 8 + 9 +
+                                                                                  28 . 8 + 9 +
+                                                                                28 8 . + 9 +
+                                                                                  36 . 9 +
+                                                                                36 9 . +
+                                                                                  45 . 
+
+
+Factorial Function and Paramorphisms
+====================================
+
+A paramorphism ``P :: B -> A`` is a recursion combinator that uses
+``dup`` on intermediate values.
+
+::
+
+    n swap [P] [pop] [[F] dupdip G] primrec
+
+With - ``n :: A`` is the "identity" for ``F`` (like 1 for
+multiplication, 0 for addition) - ``F :: (A, B) -> A`` - ``G :: B -> B``
+generates the next ``B`` value. - and lastly ``P :: B -> Bool`` detects
+the end of the series.
+
+For Factorial function (types ``A`` and ``B`` are both integer):
+
+::
+
+    n == 1
+    F == *
+    G == --
+    P == 1 <=
+
+.. code:: ipython2
+
+    define('factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec')
+
+Try it with input 3 (omitting evaluation of predicate):
+
+::
+
+    3 1 swap [1 <=] [pop] [[*] dupdip --] primrec
+    1 3      [1 <=] [pop] [[*] dupdip --] primrec
+
+    1 3 [*] dupdip --
+    1 3  * 3      --
+    3      3      --
+    3      2
+
+    3 2 [*] dupdip --
+    3 2  *  2      --
+    6       2      --
+    6       1
+
+    6 1 [1 <=] [pop] [[*] dupdip --] primrec
+
+    6 1 pop
+    6
+
+.. code:: ipython2
+
+    J('3 factorial')
+
+
+.. parsed-literal::
+
+    6
+
+
+Derive ``paramorphism`` from the form above.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    n swap [P] [pop] [[F] dupdip G] primrec
+
+    n swap [P]       [pop]     [[F] dupdip G]                  primrec
+    n [P] [swap] dip [pop]     [[F] dupdip G]                  primrec
+    n [P] [[F] dupdip G]                [[swap] dip [pop]] dip primrec
+    n [P] [F] [dupdip G]           cons [[swap] dip [pop]] dip primrec
+    n [P] [F] [G] [dupdip] swoncat cons [[swap] dip [pop]] dip primrec
+
+    paramorphism == [dupdip] swoncat cons [[swap] dip [pop]] dip primrec
+
+.. code:: ipython2
+
+    define('paramorphism == [dupdip] swoncat cons [[swap] dip [pop]] dip primrec')
+    define('factorial == 1 [1 <=] [*] [--] paramorphism')
+
+.. code:: ipython2
+
+    J('3 factorial')
+
+
+.. parsed-literal::
+
+    6
+
+
+``tails``
+=========
+
+An example of a paramorphism for lists given in the `"Bananas..."
+paper <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
+is ``tails`` which returns the list of "tails" of a list.
+
+::
+
+    [1 2 3] tails == [[] [3] [2 3]]
+
+Using ``paramorphism`` we would write:
+
+::
+
+    n == []
+    F == rest swons
+    G == rest
+    P == not
+
+    tails == [] [not] [rest swons] [rest] paramorphism
+
+.. code:: ipython2
+
+    define('tails == [] [not] [rest swons] [rest] paramorphism')
+
+.. code:: ipython2
+
+    J('[1 2 3] tails')
+
+
+.. parsed-literal::
+
+    [[] [3] [2 3]]
+
+
+.. code:: ipython2
+
+    J('25 range tails [popop] infra [sum] map')
+
+
+.. parsed-literal::
+
+    [1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210 231 253 276]
+
+
+.. code:: ipython2
+
+    J('25 range [range_sum] map')
+
+
+.. parsed-literal::
+
+    [276 253 231 210 190 171 153 136 120 105 91 78 66 55 45 36 28 21 15 10 6 3 1 0 0]
+
+
+Factoring ``rest``
+~~~~~~~~~~~~~~~~~~
+
+Right before the recursion begins we have:
+
+::
+
+    [] [1 2 3] [not] [pop] [[rest swons] dupdip rest] primrec
+
+But we might prefer to factor ``rest`` in the quote:
+
+::
+
+    [] [1 2 3] [not] [pop] [rest [swons] dupdip] primrec
+
+There's no way to do that with the ``paramorphism`` combinator as
+defined. We would have to write and use a slightly different recursion
+combinator that accepted an additional "preprocessor" function ``[H]``
+and built:
+
+::
+
+    n swap [P] [pop] [H [F] dupdip G] primrec
+
+Or just write it out manually. This is yet another place where the
+*sufficiently smart compiler* will one day automatically refactor the
+code. We could write a ``paramorphism`` combinator that checked ``[F]``
+and ``[G]`` for common prefix and extracted it.
+
+Patterns of Recursion
+=====================
+
+Our story so far...
+
+-  A combiner ``F :: (B, B) -> B``
+-  A predicate ``P :: A -> Bool`` to detect the base case
+-  A base case value ``c :: B``
+
+Hylo- Ana-, Cata-
+~~~~~~~~~~~~~~~~~
+
+::
+
+    w/ G :: A -> (A, B)
+
+    H == [P   ] [pop c ] [G          ] [dip F    ] genrec
+    A == [P   ] [pop []] [G          ] [dip swons] genrec
+    C == [[] =] [pop c ] [uncons swap] [dip F    ] genrec
+
+Para-, ?-, ?-
+~~~~~~~~~~~~~
+
+::
+
+    w/ G :: B -> B
+
+    P == c  swap [P   ] [pop] [[F    ] dupdip G          ] primrec
+    ? == [] swap [P   ] [pop] [[swons] dupdip G          ] primrec
+    ? == c  swap [[] =] [pop] [[F    ] dupdip uncons swap] primrec
+
+Four Generalizations
+====================
+
+There are at least four kinds of recursive combinator, depending on two
+choices. The first choice is whether the combiner function 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.
+
+::
+
+    H ==        [P] [pop c] [G             ] [dip F] genrec
+    H == c swap [P] [pop]   [G [F]    dip  ] [i]     genrec
+    H ==        [P] [pop c] [  [G] dupdip  ] [dip F] genrec
+    H == c swap [P] [pop]   [  [F] dupdip G] [i]     genrec
+
+Consider:
+
+::
+
+    ... a G [H] dip F                w/ a G == a' b
+    ... c a G [F] dip H                 a G == b  a'
+    ... a [G] dupdip [H] dip F          a G == a'
+    ... c a [F] dupdip G H              a G == a'
+
+1
+~
+
+::
+
+    H == [P] [pop c] [G] [dip F] genrec
+
+Iterate n times.
+
+::
+
+    ... a [P] [pop c] [G] [dip F] genrec
+    ... a  G [H] dip F
+    ... a' b [H] dip F
+    ... a' H b F
+    ... a'  G [H] dip F b F
+    ... a'' b [H] dip F b F
+    ... a'' H b F b F
+    ... a''  G [H] dip F b F b F
+    ... a''' b [H] dip F b F b F
+    ... a''' H b F b F b F
+    ... a''' pop c b F b F b F
+    ... c b F b F b F
+
+This form builds up a 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.
+
+2
+~
+
+When you can start with the identity value c on the stack and the
+combiner 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.
+
+::
+
+    H == c swap [P] [pop] [G [F] dip] primrec
+
+    ... c a G [F] dip H
+    ... c b a' [F] dip H
+    ... c b F a' H
+    ... c b F a' G [F] dip H
+    ... c b F b a'' [F] dip H
+    ... c b F b F a'' H
+    ... c b F b F a'' G [F] dip H
+    ... c b F b F b a''' [F] dip H
+    ... c b F b F b F a''' H
+    ... c b F b F b F a''' pop
+    ... c b F b F b F
+
+The end line here is the same as for above, but only because we didn't
+evaluate ``F`` when it normally would have been.
+
+3
+~
+
+If the combiner and the generator both need to work on the current value
+then ``dup`` must be used at some point, and the generator must produce
+one item instead of two (the b is instead the duplicate of a.)
+
+::
+
+    H == [P] [pop c] [[G] dupdip] [dip F] genrec
+
+    ... a [G] dupdip [H] dip F
+    ... a  G a       [H] dip F
+    ... a'   a       [H] dip F
+    ... a' H a F
+    ... a' [G] dupdip [H] dip F a F
+    ... a'  G  a'     [H] dip F a F
+    ... a''    a'     [H] dip F a F
+    ... a'' H  a' F a F
+    ... a'' [G] dupdip [H] dip F a' F a F
+    ... a''  G  a''    [H] dip F a' F a F
+    ... a'''    a''    [H] dip F a' F a F
+    ... a''' H  a'' F a' F a F
+    ... a''' pop c  a'' F a' F a F
+    ...          c  a'' F a' F a F
+
+4
+~
+
+And, last but not least, if you can combine as you go, starting with c,
+and the combiner needs to work on the current item this is the form:
+
+::
+
+    W == c swap [P] [pop] [[F] dupdip G] primrec
+
+    ... a c swap [P] [pop] [[F] dupdip G] primrec
+    ... c a [P] [pop] [[F] dupdip G] primrec
+    ... c a [F] dupdip G W
+    ... c a  F a G W
+    ... c a  F a'  W
+    ... c a  F a'  [F] dupdip G W
+    ... c a  F a'   F  a'     G W
+    ... c a  F a'   F  a''      W
+    ... c a  F a'   F  a''      [F] dupdip G W
+    ... c a  F a'   F  a''       F  a''    G W
+    ... c a  F a'   F  a''       F  a'''     W
+    ... c a  F a'   F  a''       F  a'''     pop
+    ... c a  F a'   F  a''       F
+
+Each of the four variations above can be specialized to ana- and
+catamorphic forms.
+
+.. code:: ipython2
+
+    def WTFmorphism(c, F, P, G):
+        '''Return a hylomorphism function H.'''
+    
+        def H(a, d=c):
+            if P(a):
+                result = d
+            else:
+                a, b = G(a)
+                result = H(a, F(d, b))
+            return result
+    
+        return H
+
+.. code:: ipython2
+
+    F = lambda a, b: a + b
+    P = lambda n: n <= 1
+    G = lambda n: (n - 1, n - 1)
+    
+    wtf = WTFmorphism(0, F, P, G)
+    
+    print wtf(5)
+
+
+.. parsed-literal::
+
+    10
+
+
+::
+
+    H == [P   ] [pop c ] [G          ] [dip F    ] genrec
+
+.. code:: ipython2
+
+    DefinitionWrapper.add_definitions('''
+    P == 1 <=
+    Ga == -- dup
+    Gb == --
+    c == 0
+    F == +
+    ''', D)
+
+.. code:: ipython2
+
+    V('[1 2 3] [[] =] [pop []] [uncons swap] [dip swons] genrec')
+
+
+.. parsed-literal::
+
+                                                                                                                 . [1 2 3] [[] =] [pop []] [uncons swap] [dip swons] genrec
+                                                                                                         [1 2 3] . [[] =] [pop []] [uncons swap] [dip swons] genrec
+                                                                                                  [1 2 3] [[] =] . [pop []] [uncons swap] [dip swons] genrec
+                                                                                         [1 2 3] [[] =] [pop []] . [uncons swap] [dip swons] genrec
+                                                                           [1 2 3] [[] =] [pop []] [uncons swap] . [dip swons] genrec
+                                                               [1 2 3] [[] =] [pop []] [uncons swap] [dip swons] . genrec
+              [1 2 3] [[] =] [pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] . ifte
+    [1 2 3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] [[1 2 3]] [[] =] . infra first choice i
+                                                                                                         [1 2 3] . [] = [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [1 2 3]] swaack first choice i
+                                                                                                      [1 2 3] [] . = [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [1 2 3]] swaack first choice i
+                                                                                                           False . [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [1 2 3]] swaack first choice i
+             False [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [1 2 3]] . swaack first choice i
+             [1 2 3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] [False] . first choice i
+               [1 2 3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] False . choice i
+                              [1 2 3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] . i
+                                                                                                         [1 2 3] . uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons
+                                                                                                         1 [2 3] . swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons
+                                                                                                         [2 3] 1 . [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons
+                                                      [2 3] 1 [[[] =] [pop []] [uncons swap] [dip swons] genrec] . dip swons
+                                                                                                           [2 3] . [[] =] [pop []] [uncons swap] [dip swons] genrec 1 swons
+                                                                                                    [2 3] [[] =] . [pop []] [uncons swap] [dip swons] genrec 1 swons
+                                                                                           [2 3] [[] =] [pop []] . [uncons swap] [dip swons] genrec 1 swons
+                                                                             [2 3] [[] =] [pop []] [uncons swap] . [dip swons] genrec 1 swons
+                                                                 [2 3] [[] =] [pop []] [uncons swap] [dip swons] . genrec 1 swons
+                [2 3] [[] =] [pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] . ifte 1 swons
+        [2 3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] [[2 3]] [[] =] . infra first choice i 1 swons
+                                                                                                           [2 3] . [] = [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [2 3]] swaack first choice i 1 swons
+                                                                                                        [2 3] [] . = [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [2 3]] swaack first choice i 1 swons
+                                                                                                           False . [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [2 3]] swaack first choice i 1 swons
+               False [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [2 3]] . swaack first choice i 1 swons
+               [2 3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 1 swons
+                 [2 3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] False . choice i 1 swons
+                                [2 3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] . i 1 swons
+                                                                                                           [2 3] . uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons 1 swons
+                                                                                                           2 [3] . swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons 1 swons
+                                                                                                           [3] 2 . [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons 1 swons
+                                                        [3] 2 [[[] =] [pop []] [uncons swap] [dip swons] genrec] . dip swons 1 swons
+                                                                                                             [3] . [[] =] [pop []] [uncons swap] [dip swons] genrec 2 swons 1 swons
+                                                                                                      [3] [[] =] . [pop []] [uncons swap] [dip swons] genrec 2 swons 1 swons
+                                                                                             [3] [[] =] [pop []] . [uncons swap] [dip swons] genrec 2 swons 1 swons
+                                                                               [3] [[] =] [pop []] [uncons swap] . [dip swons] genrec 2 swons 1 swons
+                                                                   [3] [[] =] [pop []] [uncons swap] [dip swons] . genrec 2 swons 1 swons
+                  [3] [[] =] [pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] . ifte 2 swons 1 swons
+            [3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] [[3]] [[] =] . infra first choice i 2 swons 1 swons
+                                                                                                             [3] . [] = [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [3]] swaack first choice i 2 swons 1 swons
+                                                                                                          [3] [] . = [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [3]] swaack first choice i 2 swons 1 swons
+                                                                                                           False . [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [3]] swaack first choice i 2 swons 1 swons
+                 False [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [3]] . swaack first choice i 2 swons 1 swons
+                 [3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 2 swons 1 swons
+                   [3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] False . choice i 2 swons 1 swons
+                                  [3] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] . i 2 swons 1 swons
+                                                                                                             [3] . uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons 2 swons 1 swons
+                                                                                                            3 [] . swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons 2 swons 1 swons
+                                                                                                            [] 3 . [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons 2 swons 1 swons
+                                                         [] 3 [[[] =] [pop []] [uncons swap] [dip swons] genrec] . dip swons 2 swons 1 swons
+                                                                                                              [] . [[] =] [pop []] [uncons swap] [dip swons] genrec 3 swons 2 swons 1 swons
+                                                                                                       [] [[] =] . [pop []] [uncons swap] [dip swons] genrec 3 swons 2 swons 1 swons
+                                                                                              [] [[] =] [pop []] . [uncons swap] [dip swons] genrec 3 swons 2 swons 1 swons
+                                                                                [] [[] =] [pop []] [uncons swap] . [dip swons] genrec 3 swons 2 swons 1 swons
+                                                                    [] [[] =] [pop []] [uncons swap] [dip swons] . genrec 3 swons 2 swons 1 swons
+                   [] [[] =] [pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] . ifte 3 swons 2 swons 1 swons
+              [] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] [[]] [[] =] . infra first choice i 3 swons 2 swons 1 swons
+                                                                                                              [] . [] = [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] []] swaack first choice i 3 swons 2 swons 1 swons
+                                                                                                           [] [] . = [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] []] swaack first choice i 3 swons 2 swons 1 swons
+                                                                                                            True . [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] []] swaack first choice i 3 swons 2 swons 1 swons
+                   True [[pop []] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] []] . swaack first choice i 3 swons 2 swons 1 swons
+                   [] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] [True] . first choice i 3 swons 2 swons 1 swons
+                     [] [uncons swap [[[] =] [pop []] [uncons swap] [dip swons] genrec] dip swons] [pop []] True . choice i 3 swons 2 swons 1 swons
+                                                                                                     [] [pop []] . i 3 swons 2 swons 1 swons
+                                                                                                              [] . pop [] 3 swons 2 swons 1 swons
+                                                                                                                 . [] 3 swons 2 swons 1 swons
+                                                                                                              [] . 3 swons 2 swons 1 swons
+                                                                                                            [] 3 . swons 2 swons 1 swons
+                                                                                                            [] 3 . swap cons 2 swons 1 swons
+                                                                                                            3 [] . cons 2 swons 1 swons
+                                                                                                             [3] . 2 swons 1 swons
+                                                                                                           [3] 2 . swons 1 swons
+                                                                                                           [3] 2 . swap cons 1 swons
+                                                                                                           2 [3] . cons 1 swons
+                                                                                                           [2 3] . 1 swons
+                                                                                                         [2 3] 1 . swons
+                                                                                                         [2 3] 1 . swap cons
+                                                                                                         1 [2 3] . cons
+                                                                                                         [1 2 3] . 
+
+
+.. code:: ipython2
+
+    V('3 [P] [pop c] [Ga] [dip F] genrec')
+
+
+.. parsed-literal::
+
+                                                                   . 3 [P] [pop c] [Ga] [dip F] genrec
+                                                                 3 . [P] [pop c] [Ga] [dip F] genrec
+                                                             3 [P] . [pop c] [Ga] [dip F] genrec
+                                                     3 [P] [pop c] . [Ga] [dip F] genrec
+                                                3 [P] [pop c] [Ga] . [dip F] genrec
+                                        3 [P] [pop c] [Ga] [dip F] . genrec
+        3 [P] [pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] . ifte
+    3 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] [pop c] [3] [P] . infra first choice i
+                                                                 3 . P [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 3] swaack first choice i
+                                                                 3 . 1 <= [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 3] swaack first choice i
+                                                               3 1 . <= [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 3] swaack first choice i
+                                                             False . [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 3] swaack first choice i
+    False [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 3] . swaack first choice i
+    3 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] [pop c] [False] . first choice i
+      3 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] [pop c] False . choice i
+                    3 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] . i
+                                                                 3 . Ga [[P] [pop c] [Ga] [dip F] genrec] dip F
+                                                                 3 . -- dup [[P] [pop c] [Ga] [dip F] genrec] dip F
+                                                                 2 . dup [[P] [pop c] [Ga] [dip F] genrec] dip F
+                                                               2 2 . [[P] [pop c] [Ga] [dip F] genrec] dip F
+                             2 2 [[P] [pop c] [Ga] [dip F] genrec] . dip F
+                                                                 2 . [P] [pop c] [Ga] [dip F] genrec 2 F
+                                                             2 [P] . [pop c] [Ga] [dip F] genrec 2 F
+                                                     2 [P] [pop c] . [Ga] [dip F] genrec 2 F
+                                                2 [P] [pop c] [Ga] . [dip F] genrec 2 F
+                                        2 [P] [pop c] [Ga] [dip F] . genrec 2 F
+        2 [P] [pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] . ifte 2 F
+    2 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] [pop c] [2] [P] . infra first choice i 2 F
+                                                                 2 . P [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 2] swaack first choice i 2 F
+                                                                 2 . 1 <= [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 2] swaack first choice i 2 F
+                                                               2 1 . <= [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 2] swaack first choice i 2 F
+                                                             False . [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 2] swaack first choice i 2 F
+    False [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 2] . swaack first choice i 2 F
+    2 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] [pop c] [False] . first choice i 2 F
+      2 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] [pop c] False . choice i 2 F
+                    2 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] . i 2 F
+                                                                 2 . Ga [[P] [pop c] [Ga] [dip F] genrec] dip F 2 F
+                                                                 2 . -- dup [[P] [pop c] [Ga] [dip F] genrec] dip F 2 F
+                                                                 1 . dup [[P] [pop c] [Ga] [dip F] genrec] dip F 2 F
+                                                               1 1 . [[P] [pop c] [Ga] [dip F] genrec] dip F 2 F
+                             1 1 [[P] [pop c] [Ga] [dip F] genrec] . dip F 2 F
+                                                                 1 . [P] [pop c] [Ga] [dip F] genrec 1 F 2 F
+                                                             1 [P] . [pop c] [Ga] [dip F] genrec 1 F 2 F
+                                                     1 [P] [pop c] . [Ga] [dip F] genrec 1 F 2 F
+                                                1 [P] [pop c] [Ga] . [dip F] genrec 1 F 2 F
+                                        1 [P] [pop c] [Ga] [dip F] . genrec 1 F 2 F
+        1 [P] [pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] . ifte 1 F 2 F
+    1 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] [pop c] [1] [P] . infra first choice i 1 F 2 F
+                                                                 1 . P [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 1] swaack first choice i 1 F 2 F
+                                                                 1 . 1 <= [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 1] swaack first choice i 1 F 2 F
+                                                               1 1 . <= [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 1] swaack first choice i 1 F 2 F
+                                                              True . [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 1] swaack first choice i 1 F 2 F
+     True [[pop c] [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] 1] . swaack first choice i 1 F 2 F
+     1 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] [pop c] [True] . first choice i 1 F 2 F
+       1 [Ga [[P] [pop c] [Ga] [dip F] genrec] dip F] [pop c] True . choice i 1 F 2 F
+                                                         1 [pop c] . i 1 F 2 F
+                                                                 1 . pop c 1 F 2 F
+                                                                   . c 1 F 2 F
+                                                                   . 0 1 F 2 F
+                                                                 0 . 1 F 2 F
+                                                               0 1 . F 2 F
+                                                               0 1 . + 2 F
+                                                                 1 . 2 F
+                                                               1 2 . F
+                                                               1 2 . +
+                                                                 3 . 
+
+
+.. code:: ipython2
+
+    V('3 [P] [pop []] [Ga] [dip swons] genrec')
+
+
+.. parsed-literal::
+
+                                                                             . 3 [P] [pop []] [Ga] [dip swons] genrec
+                                                                           3 . [P] [pop []] [Ga] [dip swons] genrec
+                                                                       3 [P] . [pop []] [Ga] [dip swons] genrec
+                                                              3 [P] [pop []] . [Ga] [dip swons] genrec
+                                                         3 [P] [pop []] [Ga] . [dip swons] genrec
+                                             3 [P] [pop []] [Ga] [dip swons] . genrec
+        3 [P] [pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] . ifte
+    3 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] [pop []] [3] [P] . infra first choice i
+                                                                           3 . P [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 3] swaack first choice i
+                                                                           3 . 1 <= [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 3] swaack first choice i
+                                                                         3 1 . <= [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 3] swaack first choice i
+                                                                       False . [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 3] swaack first choice i
+    False [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 3] . swaack first choice i
+    3 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] [pop []] [False] . first choice i
+      3 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] [pop []] False . choice i
+                     3 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] . i
+                                                                           3 . Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons
+                                                                           3 . -- dup [[P] [pop []] [Ga] [dip swons] genrec] dip swons
+                                                                           2 . dup [[P] [pop []] [Ga] [dip swons] genrec] dip swons
+                                                                         2 2 . [[P] [pop []] [Ga] [dip swons] genrec] dip swons
+                                  2 2 [[P] [pop []] [Ga] [dip swons] genrec] . dip swons
+                                                                           2 . [P] [pop []] [Ga] [dip swons] genrec 2 swons
+                                                                       2 [P] . [pop []] [Ga] [dip swons] genrec 2 swons
+                                                              2 [P] [pop []] . [Ga] [dip swons] genrec 2 swons
+                                                         2 [P] [pop []] [Ga] . [dip swons] genrec 2 swons
+                                             2 [P] [pop []] [Ga] [dip swons] . genrec 2 swons
+        2 [P] [pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] . ifte 2 swons
+    2 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] [pop []] [2] [P] . infra first choice i 2 swons
+                                                                           2 . P [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 2] swaack first choice i 2 swons
+                                                                           2 . 1 <= [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 2] swaack first choice i 2 swons
+                                                                         2 1 . <= [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 2] swaack first choice i 2 swons
+                                                                       False . [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 2] swaack first choice i 2 swons
+    False [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 2] . swaack first choice i 2 swons
+    2 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] [pop []] [False] . first choice i 2 swons
+      2 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] [pop []] False . choice i 2 swons
+                     2 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] . i 2 swons
+                                                                           2 . Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons 2 swons
+                                                                           2 . -- dup [[P] [pop []] [Ga] [dip swons] genrec] dip swons 2 swons
+                                                                           1 . dup [[P] [pop []] [Ga] [dip swons] genrec] dip swons 2 swons
+                                                                         1 1 . [[P] [pop []] [Ga] [dip swons] genrec] dip swons 2 swons
+                                  1 1 [[P] [pop []] [Ga] [dip swons] genrec] . dip swons 2 swons
+                                                                           1 . [P] [pop []] [Ga] [dip swons] genrec 1 swons 2 swons
+                                                                       1 [P] . [pop []] [Ga] [dip swons] genrec 1 swons 2 swons
+                                                              1 [P] [pop []] . [Ga] [dip swons] genrec 1 swons 2 swons
+                                                         1 [P] [pop []] [Ga] . [dip swons] genrec 1 swons 2 swons
+                                             1 [P] [pop []] [Ga] [dip swons] . genrec 1 swons 2 swons
+        1 [P] [pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] . ifte 1 swons 2 swons
+    1 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] [pop []] [1] [P] . infra first choice i 1 swons 2 swons
+                                                                           1 . P [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 1] swaack first choice i 1 swons 2 swons
+                                                                           1 . 1 <= [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 1] swaack first choice i 1 swons 2 swons
+                                                                         1 1 . <= [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 1] swaack first choice i 1 swons 2 swons
+                                                                        True . [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 1] swaack first choice i 1 swons 2 swons
+     True [[pop []] [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] 1] . swaack first choice i 1 swons 2 swons
+     1 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] [pop []] [True] . first choice i 1 swons 2 swons
+       1 [Ga [[P] [pop []] [Ga] [dip swons] genrec] dip swons] [pop []] True . choice i 1 swons 2 swons
+                                                                  1 [pop []] . i 1 swons 2 swons
+                                                                           1 . pop [] 1 swons 2 swons
+                                                                             . [] 1 swons 2 swons
+                                                                          [] . 1 swons 2 swons
+                                                                        [] 1 . swons 2 swons
+                                                                        [] 1 . swap cons 2 swons
+                                                                        1 [] . cons 2 swons
+                                                                         [1] . 2 swons
+                                                                       [1] 2 . swons
+                                                                       [1] 2 . swap cons
+                                                                       2 [1] . cons
+                                                                       [2 1] . 
+
+
+.. code:: ipython2
+
+    V('[2 1] [[] =] [pop c ] [uncons swap] [dip F] genrec')
+
+
+.. parsed-literal::
+
+                                                                                                   . [2 1] [[] =] [pop c] [uncons swap] [dip F] genrec
+                                                                                             [2 1] . [[] =] [pop c] [uncons swap] [dip F] genrec
+                                                                                      [2 1] [[] =] . [pop c] [uncons swap] [dip F] genrec
+                                                                              [2 1] [[] =] [pop c] . [uncons swap] [dip F] genrec
+                                                                [2 1] [[] =] [pop c] [uncons swap] . [dip F] genrec
+                                                        [2 1] [[] =] [pop c] [uncons swap] [dip F] . genrec
+            [2 1] [[] =] [pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] . ifte
+    [2 1] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [pop c] [[2 1]] [[] =] . infra first choice i
+                                                                                             [2 1] . [] = [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [2 1]] swaack first choice i
+                                                                                          [2 1] [] . = [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [2 1]] swaack first choice i
+                                                                                             False . [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [2 1]] swaack first choice i
+           False [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [2 1]] . swaack first choice i
+           [2 1] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [pop c] [False] . first choice i
+             [2 1] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [pop c] False . choice i
+                           [2 1] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] . i
+                                                                                             [2 1] . uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F
+                                                                                             2 [1] . swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F
+                                                                                             [1] 2 . [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F
+                                               [1] 2 [[[] =] [pop c] [uncons swap] [dip F] genrec] . dip F
+                                                                                               [1] . [[] =] [pop c] [uncons swap] [dip F] genrec 2 F
+                                                                                        [1] [[] =] . [pop c] [uncons swap] [dip F] genrec 2 F
+                                                                                [1] [[] =] [pop c] . [uncons swap] [dip F] genrec 2 F
+                                                                  [1] [[] =] [pop c] [uncons swap] . [dip F] genrec 2 F
+                                                          [1] [[] =] [pop c] [uncons swap] [dip F] . genrec 2 F
+              [1] [[] =] [pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] . ifte 2 F
+        [1] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [pop c] [[1]] [[] =] . infra first choice i 2 F
+                                                                                               [1] . [] = [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [1]] swaack first choice i 2 F
+                                                                                            [1] [] . = [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [1]] swaack first choice i 2 F
+                                                                                             False . [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [1]] swaack first choice i 2 F
+             False [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [1]] . swaack first choice i 2 F
+             [1] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [pop c] [False] . first choice i 2 F
+               [1] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [pop c] False . choice i 2 F
+                             [1] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] . i 2 F
+                                                                                               [1] . uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F 2 F
+                                                                                              1 [] . swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F 2 F
+                                                                                              [] 1 . [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F 2 F
+                                                [] 1 [[[] =] [pop c] [uncons swap] [dip F] genrec] . dip F 2 F
+                                                                                                [] . [[] =] [pop c] [uncons swap] [dip F] genrec 1 F 2 F
+                                                                                         [] [[] =] . [pop c] [uncons swap] [dip F] genrec 1 F 2 F
+                                                                                 [] [[] =] [pop c] . [uncons swap] [dip F] genrec 1 F 2 F
+                                                                   [] [[] =] [pop c] [uncons swap] . [dip F] genrec 1 F 2 F
+                                                           [] [[] =] [pop c] [uncons swap] [dip F] . genrec 1 F 2 F
+               [] [[] =] [pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] . ifte 1 F 2 F
+          [] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [pop c] [[]] [[] =] . infra first choice i 1 F 2 F
+                                                                                                [] . [] = [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] []] swaack first choice i 1 F 2 F
+                                                                                             [] [] . = [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] []] swaack first choice i 1 F 2 F
+                                                                                              True . [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] []] swaack first choice i 1 F 2 F
+               True [[pop c] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] []] . swaack first choice i 1 F 2 F
+               [] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [pop c] [True] . first choice i 1 F 2 F
+                 [] [uncons swap [[[] =] [pop c] [uncons swap] [dip F] genrec] dip F] [pop c] True . choice i 1 F 2 F
+                                                                                        [] [pop c] . i 1 F 2 F
+                                                                                                [] . pop c 1 F 2 F
+                                                                                                   . c 1 F 2 F
+                                                                                                   . 0 1 F 2 F
+                                                                                                 0 . 1 F 2 F
+                                                                                               0 1 . F 2 F
+                                                                                               0 1 . + 2 F
+                                                                                                 1 . 2 F
+                                                                                               1 2 . F
+                                                                                               1 2 . +
+                                                                                                 3 . 
+
+
+Appendix - Fun with Symbols
+---------------------------
+
+::
+
+    |[ (c, F), (G, P) ]| == (|c, F|) • [(G, P)]
+
+`"Bananas, Lenses, & Barbed
+Wire" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
+
+::
+
+    (|...|)  [(...)]  [<...>]
+
+I think they are having slightly too much fun with the symbols.
+
+"Too much is always better than not enough."
+
+Tree with node and list of trees.
+=================================
+
+::
+
+    tree = [] | [node [tree*]]
+
+``treestep``
+~~~~~~~~~~~~
+
+::
+
+    tree z [C] [N] treestep
+
+
+       [] z [C] [N] treestep
+    ---------------------------
+          z
+
+
+       [node [tree*]] z [C] [N] treestep
+    --------------------------------------- w/ K == z [C] [N] treestep
+           node N [tree*] [K] map C
+
+Derive the recursive form.
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    K == [not] [pop z] [J] ifte
+
+
+           [node [tree*]] J
+    ------------------------------
+       node N [tree*] [K] map C
+
+
+    J == .. [N] .. [K] .. [C] ..
+
+    [node [tree*]] uncons [N] dip
+    node [[tree*]]        [N] dip
+    node N [[tree*]]
+
+    node N [[tree*]] i [K] map
+    node N  [tree*]    [K] map
+    node N  [K.tree*]
+
+    J == uncons [N] dip i [K] map [C] i
+
+    K == [not] [pop z] [uncons [N] dip i [K] map [C] i] ifte
+    K == [not] [pop z] [uncons [N] dip i]   [map [C] i] genrec
+
+Extract the givens to parameterize the program.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    [not] [pop z]                   [uncons [N] dip unquote] [map [C] i] genrec
+    [not] [z]         [pop] swoncat [uncons [N] dip unquote] [map [C] i] genrec
+    [not]  z     unit [pop] swoncat [uncons [N] dip unquote] [map [C] i] genrec
+    z [not] swap unit [pop] swoncat [uncons [N] dip unquote] [map [C] i] genrec
+      \............TS0............/
+    z TS0 [uncons [N] dip unquote]                      [map [C] i] genrec
+    z [uncons [N] dip unquote]                [TS0] dip [map [C] i] genrec
+    z [[N] dip unquote]      [uncons] swoncat [TS0] dip [map [C] i] genrec
+    z [N] [dip unquote] cons [uncons] swoncat [TS0] dip [map [C] i] genrec
+          \...........TS1.................../
+    z [N] TS1 [TS0] dip [map [C] i]                       genrec
+    z [N]               [map [C] i]            [TS1 [TS0] dip] dip      genrec
+    z [N]               [map  C   ]            [TS1 [TS0] dip] dip      genrec
+    z [N]                    [C] [map] swoncat [TS1 [TS0] dip] dip genrec
+    z [C] [N] swap               [map] swoncat [TS1 [TS0] dip] dip genrec
+
+::
+
+         TS0 == [not] swap unit [pop] swoncat
+         TS1 == [dip i] cons [uncons] swoncat
+    treestep == swap [map] swoncat [TS1 [TS0] dip] dip genrec
+
+::
+
+       [] 0 [C] [N] treestep
+    ---------------------------
+          0
+
+
+          [n [tree*]] 0 [sum +] [] treestep
+       --------------------------------------------------
+           n [tree*] [0 [sum +] [] treestep] map sum +
+
+.. code:: ipython2
+
+    DefinitionWrapper.add_definitions('''
+    
+         TS0 == [not] swap unit [pop] swoncat
+         TS1 == [dip i] cons [uncons] swoncat
+    treestep == swap [map] swoncat [TS1 [TS0] dip] dip genrec
+    
+    ''', D)
+
+.. code:: ipython2
+
+    V('[] 0 [sum +] [] treestep')
+
+
+.. parsed-literal::
+
+                                                                                                           . [] 0 [sum +] [] treestep
+                                                                                                        [] . 0 [sum +] [] treestep
+                                                                                                      [] 0 . [sum +] [] treestep
+                                                                                              [] 0 [sum +] . [] treestep
+                                                                                           [] 0 [sum +] [] . treestep
+                                                                                           [] 0 [sum +] [] . swap [map] swoncat [TS1 [TS0] dip] dip genrec
+                                                                                           [] 0 [] [sum +] . [map] swoncat [TS1 [TS0] dip] dip genrec
+                                                                                     [] 0 [] [sum +] [map] . swoncat [TS1 [TS0] dip] dip genrec
+                                                                                     [] 0 [] [sum +] [map] . swap concat [TS1 [TS0] dip] dip genrec
+                                                                                     [] 0 [] [map] [sum +] . concat [TS1 [TS0] dip] dip genrec
+                                                                                       [] 0 [] [map sum +] . [TS1 [TS0] dip] dip genrec
+                                                                       [] 0 [] [map sum +] [TS1 [TS0] dip] . dip genrec
+                                                                                                   [] 0 [] . TS1 [TS0] dip [map sum +] genrec
+                                                                                                   [] 0 [] . [dip i] cons [uncons] swoncat [TS0] dip [map sum +] genrec
+                                                                                           [] 0 [] [dip i] . cons [uncons] swoncat [TS0] dip [map sum +] genrec
+                                                                                           [] 0 [[] dip i] . [uncons] swoncat [TS0] dip [map sum +] genrec
+                                                                                  [] 0 [[] dip i] [uncons] . swoncat [TS0] dip [map sum +] genrec
+                                                                                  [] 0 [[] dip i] [uncons] . swap concat [TS0] dip [map sum +] genrec
+                                                                                  [] 0 [uncons] [[] dip i] . concat [TS0] dip [map sum +] genrec
+                                                                                    [] 0 [uncons [] dip i] . [TS0] dip [map sum +] genrec
+                                                                              [] 0 [uncons [] dip i] [TS0] . dip [map sum +] genrec
+                                                                                                      [] 0 . TS0 [uncons [] dip i] [map sum +] genrec
+                                                                                                      [] 0 . [not] swap unit [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                [] 0 [not] . swap unit [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                [] [not] 0 . unit [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                [] [not] 0 . [] cons [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                             [] [not] 0 [] . cons [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                              [] [not] [0] . [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                        [] [not] [0] [pop] . swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                        [] [not] [0] [pop] . swap concat [uncons [] dip i] [map sum +] genrec
+                                                                                        [] [not] [pop] [0] . concat [uncons [] dip i] [map sum +] genrec
+                                                                                          [] [not] [pop 0] . [uncons [] dip i] [map sum +] genrec
+                                                                        [] [not] [pop 0] [uncons [] dip i] . [map sum +] genrec
+                                                            [] [not] [pop 0] [uncons [] dip i] [map sum +] . genrec
+         [] [not] [pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] . ifte
+    [] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [[]] [not] . infra first choice i
+                                                                                                        [] . not [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] []] swaack first choice i
+                                                                                                      True . [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] []] swaack first choice i
+        True [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] []] . swaack first choice i
+        [] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [True] . first choice i
+          [] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] True . choice i
+                                                                                                [] [pop 0] . i
+                                                                                                        [] . pop 0
+                                                                                                           . 0
+                                                                                                         0 . 
+
+
+.. code:: ipython2
+
+    V('[23 []] 0 [sum +] [] treestep')
+
+
+.. parsed-literal::
+
+                                                                                                                     . [23 []] 0 [sum +] [] treestep
+                                                                                                             [23 []] . 0 [sum +] [] treestep
+                                                                                                           [23 []] 0 . [sum +] [] treestep
+                                                                                                   [23 []] 0 [sum +] . [] treestep
+                                                                                                [23 []] 0 [sum +] [] . treestep
+                                                                                                [23 []] 0 [sum +] [] . swap [map] swoncat [TS1 [TS0] dip] dip genrec
+                                                                                                [23 []] 0 [] [sum +] . [map] swoncat [TS1 [TS0] dip] dip genrec
+                                                                                          [23 []] 0 [] [sum +] [map] . swoncat [TS1 [TS0] dip] dip genrec
+                                                                                          [23 []] 0 [] [sum +] [map] . swap concat [TS1 [TS0] dip] dip genrec
+                                                                                          [23 []] 0 [] [map] [sum +] . concat [TS1 [TS0] dip] dip genrec
+                                                                                            [23 []] 0 [] [map sum +] . [TS1 [TS0] dip] dip genrec
+                                                                            [23 []] 0 [] [map sum +] [TS1 [TS0] dip] . dip genrec
+                                                                                                        [23 []] 0 [] . TS1 [TS0] dip [map sum +] genrec
+                                                                                                        [23 []] 0 [] . [dip i] cons [uncons] swoncat [TS0] dip [map sum +] genrec
+                                                                                                [23 []] 0 [] [dip i] . cons [uncons] swoncat [TS0] dip [map sum +] genrec
+                                                                                                [23 []] 0 [[] dip i] . [uncons] swoncat [TS0] dip [map sum +] genrec
+                                                                                       [23 []] 0 [[] dip i] [uncons] . swoncat [TS0] dip [map sum +] genrec
+                                                                                       [23 []] 0 [[] dip i] [uncons] . swap concat [TS0] dip [map sum +] genrec
+                                                                                       [23 []] 0 [uncons] [[] dip i] . concat [TS0] dip [map sum +] genrec
+                                                                                         [23 []] 0 [uncons [] dip i] . [TS0] dip [map sum +] genrec
+                                                                                   [23 []] 0 [uncons [] dip i] [TS0] . dip [map sum +] genrec
+                                                                                                           [23 []] 0 . TS0 [uncons [] dip i] [map sum +] genrec
+                                                                                                           [23 []] 0 . [not] swap unit [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                     [23 []] 0 [not] . swap unit [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                     [23 []] [not] 0 . unit [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                     [23 []] [not] 0 . [] cons [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                  [23 []] [not] 0 [] . cons [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                   [23 []] [not] [0] . [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                             [23 []] [not] [0] [pop] . swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                             [23 []] [not] [0] [pop] . swap concat [uncons [] dip i] [map sum +] genrec
+                                                                                             [23 []] [not] [pop] [0] . concat [uncons [] dip i] [map sum +] genrec
+                                                                                               [23 []] [not] [pop 0] . [uncons [] dip i] [map sum +] genrec
+                                                                             [23 []] [not] [pop 0] [uncons [] dip i] . [map sum +] genrec
+                                                                 [23 []] [not] [pop 0] [uncons [] dip i] [map sum +] . genrec
+              [23 []] [not] [pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] . ifte
+    [23 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [[23 []]] [not] . infra first choice i
+                                                                                                             [23 []] . not [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [23 []]] swaack first choice i
+                                                                                                               False . [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [23 []]] swaack first choice i
+            False [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [23 []]] . swaack first choice i
+            [23 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [False] . first choice i
+              [23 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] False . choice i
+                            [23 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] . i
+                                                                                                             [23 []] . uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                             23 [[]] . [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                          23 [[]] [] . dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                                  23 . [[]] i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                             23 [[]] . i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                                  23 . [] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                               23 [] . [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                          23 [] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] . map sum +
+                                                                                                               23 [] . sum +
+                                                                                                               23 [] . 0 [+] catamorphism +
+                                                                                                             23 [] 0 . [+] catamorphism +
+                                                                                                         23 [] 0 [+] . catamorphism +
+                                                                                                         23 [] 0 [+] . [[] =] roll> [uncons swap] swap hylomorphism +
+                                                                                                  23 [] 0 [+] [[] =] . roll> [uncons swap] swap hylomorphism +
+                                                                                                  23 [] [[] =] 0 [+] . [uncons swap] swap hylomorphism +
+                                                                                    23 [] [[] =] 0 [+] [uncons swap] . swap hylomorphism +
+                                                                                    23 [] [[] =] 0 [uncons swap] [+] . hylomorphism +
+                                                                                    23 [] [[] =] 0 [uncons swap] [+] . [unit [pop] swoncat] dipd [dip] swoncat genrec +
+                                                               23 [] [[] =] 0 [uncons swap] [+] [unit [pop] swoncat] . dipd [dip] swoncat genrec +
+                                                                                                      23 [] [[] =] 0 . unit [pop] swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                      23 [] [[] =] 0 . [] cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                   23 [] [[] =] 0 [] . cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                    23 [] [[] =] [0] . [pop] swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                              23 [] [[] =] [0] [pop] . swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                              23 [] [[] =] [0] [pop] . swap concat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                              23 [] [[] =] [pop] [0] . concat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                23 [] [[] =] [pop 0] . [uncons swap] [+] [dip] swoncat genrec +
+                                                                                  23 [] [[] =] [pop 0] [uncons swap] . [+] [dip] swoncat genrec +
+                                                                              23 [] [[] =] [pop 0] [uncons swap] [+] . [dip] swoncat genrec +
+                                                                        23 [] [[] =] [pop 0] [uncons swap] [+] [dip] . swoncat genrec +
+                                                                        23 [] [[] =] [pop 0] [uncons swap] [+] [dip] . swap concat genrec +
+                                                                        23 [] [[] =] [pop 0] [uncons swap] [dip] [+] . concat genrec +
+                                                                          23 [] [[] =] [pop 0] [uncons swap] [dip +] . genrec +
+                              23 [] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte +
+                      23 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[] 23] [[] =] . infra first choice i +
+                                                                                                               23 [] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 23] swaack first choice i +
+                                                                                                            23 [] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 23] swaack first choice i +
+                                                                                                             23 True . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 23] swaack first choice i +
+                           23 True [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 23] . swaack first choice i +
+                           23 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [True 23] . first choice i +
+                                23 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] True . choice i +
+                                                                                                       23 [] [pop 0] . i +
+                                                                                                               23 [] . pop 0 +
+                                                                                                                  23 . 0 +
+                                                                                                                23 0 . +
+                                                                                                                  23 . 
+
+
+.. code:: ipython2
+
+    V('[23 [[2 []] [3 []]]] 0 [sum +] [] treestep')
+
+
+.. parsed-literal::
+
+                                                                                                                                                                      . [23 [[2 []] [3 []]]] 0 [sum +] [] treestep
+                                                                                                                                                 [23 [[2 []] [3 []]]] . 0 [sum +] [] treestep
+                                                                                                                                               [23 [[2 []] [3 []]]] 0 . [sum +] [] treestep
+                                                                                                                                       [23 [[2 []] [3 []]]] 0 [sum +] . [] treestep
+                                                                                                                                    [23 [[2 []] [3 []]]] 0 [sum +] [] . treestep
+                                                                                                                                    [23 [[2 []] [3 []]]] 0 [sum +] [] . swap [map] swoncat [TS1 [TS0] dip] dip genrec
+                                                                                                                                    [23 [[2 []] [3 []]]] 0 [] [sum +] . [map] swoncat [TS1 [TS0] dip] dip genrec
+                                                                                                                              [23 [[2 []] [3 []]]] 0 [] [sum +] [map] . swoncat [TS1 [TS0] dip] dip genrec
+                                                                                                                              [23 [[2 []] [3 []]]] 0 [] [sum +] [map] . swap concat [TS1 [TS0] dip] dip genrec
+                                                                                                                              [23 [[2 []] [3 []]]] 0 [] [map] [sum +] . concat [TS1 [TS0] dip] dip genrec
+                                                                                                                                [23 [[2 []] [3 []]]] 0 [] [map sum +] . [TS1 [TS0] dip] dip genrec
+                                                                                                                [23 [[2 []] [3 []]]] 0 [] [map sum +] [TS1 [TS0] dip] . dip genrec
+                                                                                                                                            [23 [[2 []] [3 []]]] 0 [] . TS1 [TS0] dip [map sum +] genrec
+                                                                                                                                            [23 [[2 []] [3 []]]] 0 [] . [dip i] cons [uncons] swoncat [TS0] dip [map sum +] genrec
+                                                                                                                                    [23 [[2 []] [3 []]]] 0 [] [dip i] . cons [uncons] swoncat [TS0] dip [map sum +] genrec
+                                                                                                                                    [23 [[2 []] [3 []]]] 0 [[] dip i] . [uncons] swoncat [TS0] dip [map sum +] genrec
+                                                                                                                           [23 [[2 []] [3 []]]] 0 [[] dip i] [uncons] . swoncat [TS0] dip [map sum +] genrec
+                                                                                                                           [23 [[2 []] [3 []]]] 0 [[] dip i] [uncons] . swap concat [TS0] dip [map sum +] genrec
+                                                                                                                           [23 [[2 []] [3 []]]] 0 [uncons] [[] dip i] . concat [TS0] dip [map sum +] genrec
+                                                                                                                             [23 [[2 []] [3 []]]] 0 [uncons [] dip i] . [TS0] dip [map sum +] genrec
+                                                                                                                       [23 [[2 []] [3 []]]] 0 [uncons [] dip i] [TS0] . dip [map sum +] genrec
+                                                                                                                                               [23 [[2 []] [3 []]]] 0 . TS0 [uncons [] dip i] [map sum +] genrec
+                                                                                                                                               [23 [[2 []] [3 []]]] 0 . [not] swap unit [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                                                         [23 [[2 []] [3 []]]] 0 [not] . swap unit [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                                                         [23 [[2 []] [3 []]]] [not] 0 . unit [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                                                         [23 [[2 []] [3 []]]] [not] 0 . [] cons [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                                                      [23 [[2 []] [3 []]]] [not] 0 [] . cons [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                                                       [23 [[2 []] [3 []]]] [not] [0] . [pop] swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                                                 [23 [[2 []] [3 []]]] [not] [0] [pop] . swoncat [uncons [] dip i] [map sum +] genrec
+                                                                                                                                 [23 [[2 []] [3 []]]] [not] [0] [pop] . swap concat [uncons [] dip i] [map sum +] genrec
+                                                                                                                                 [23 [[2 []] [3 []]]] [not] [pop] [0] . concat [uncons [] dip i] [map sum +] genrec
+                                                                                                                                   [23 [[2 []] [3 []]]] [not] [pop 0] . [uncons [] dip i] [map sum +] genrec
+                                                                                                                 [23 [[2 []] [3 []]]] [not] [pop 0] [uncons [] dip i] . [map sum +] genrec
+                                                                                                     [23 [[2 []] [3 []]]] [not] [pop 0] [uncons [] dip i] [map sum +] . genrec
+                                                  [23 [[2 []] [3 []]]] [not] [pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] . ifte
+                           [23 [[2 []] [3 []]]] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [[23 [[2 []] [3 []]]]] [not] . infra first choice i
+                                                                                                                                                 [23 [[2 []] [3 []]]] . not [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [23 [[2 []] [3 []]]]] swaack first choice i
+                                                                                                                                                                False . [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [23 [[2 []] [3 []]]]] swaack first choice i
+                                                False [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [23 [[2 []] [3 []]]]] . swaack first choice i
+                                                [23 [[2 []] [3 []]]] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [False] . first choice i
+                                                  [23 [[2 []] [3 []]]] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] False . choice i
+                                                                [23 [[2 []] [3 []]]] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] . i
+                                                                                                                                                 [23 [[2 []] [3 []]]] . uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                                                                 23 [[[2 []] [3 []]]] . [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                                                              23 [[[2 []] [3 []]]] [] . dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                                                                                   23 . [[[2 []] [3 []]]] i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                                                                 23 [[[2 []] [3 []]]] . i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                                                                                   23 . [[2 []] [3 []]] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                                                                                   23 [[2 []] [3 []]] . [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +
+                                                                                              23 [[2 []] [3 []]] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] . map sum +
+    23 [] [[[3 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first] . infra sum +
+                                                                                                                                                                      . [[3 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                          [[3 []] 23] . [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                     [[3 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] . infra first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                            23 [3 []] . [not] [pop 0] [uncons [] dip i] [map sum +] genrec [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                      23 [3 []] [not] . [pop 0] [uncons [] dip i] [map sum +] genrec [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                              23 [3 []] [not] [pop 0] . [uncons [] dip i] [map sum +] genrec [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                            23 [3 []] [not] [pop 0] [uncons [] dip i] . [map sum +] genrec [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                23 [3 []] [not] [pop 0] [uncons [] dip i] [map sum +] . genrec [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                             23 [3 []] [not] [pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] . ifte [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                 23 [3 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [[3 []] 23] [not] . infra first choice i [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                            23 [3 []] . not [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [3 []] 23] swaack first choice i [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                             23 False . [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [3 []] 23] swaack first choice i [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                        23 False [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [3 []] 23] . swaack first choice i [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                        23 [3 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [False 23] . first choice i [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                             23 [3 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] False . choice i [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                           23 [3 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] . i [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                            23 [3 []] . uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                            23 3 [[]] . [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                         23 3 [[]] [] . dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                                 23 3 . [[]] i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                            23 3 [[]] . i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                                 23 3 . [] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                              23 3 [] . [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                         23 3 [] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] . map sum + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                              23 3 [] . sum + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                              23 3 [] . 0 [+] catamorphism + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                            23 3 [] 0 . [+] catamorphism + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                        23 3 [] 0 [+] . catamorphism + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                        23 3 [] 0 [+] . [[] =] roll> [uncons swap] swap hylomorphism + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                 23 3 [] 0 [+] [[] =] . roll> [uncons swap] swap hylomorphism + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                 23 3 [] [[] =] 0 [+] . [uncons swap] swap hylomorphism + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                   23 3 [] [[] =] 0 [+] [uncons swap] . swap hylomorphism + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                   23 3 [] [[] =] 0 [uncons swap] [+] . hylomorphism + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                   23 3 [] [[] =] 0 [uncons swap] [+] . [unit [pop] swoncat] dipd [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                              23 3 [] [[] =] 0 [uncons swap] [+] [unit [pop] swoncat] . dipd [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                     23 3 [] [[] =] 0 . unit [pop] swoncat [uncons swap] [+] [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                     23 3 [] [[] =] 0 . [] cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                  23 3 [] [[] =] 0 [] . cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                   23 3 [] [[] =] [0] . [pop] swoncat [uncons swap] [+] [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                             23 3 [] [[] =] [0] [pop] . swoncat [uncons swap] [+] [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                             23 3 [] [[] =] [0] [pop] . swap concat [uncons swap] [+] [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                             23 3 [] [[] =] [pop] [0] . concat [uncons swap] [+] [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                               23 3 [] [[] =] [pop 0] . [uncons swap] [+] [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                 23 3 [] [[] =] [pop 0] [uncons swap] . [+] [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                             23 3 [] [[] =] [pop 0] [uncons swap] [+] . [dip] swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                       23 3 [] [[] =] [pop 0] [uncons swap] [+] [dip] . swoncat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                       23 3 [] [[] =] [pop 0] [uncons swap] [+] [dip] . swap concat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                       23 3 [] [[] =] [pop 0] [uncons swap] [dip] [+] . concat genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                         23 3 [] [[] =] [pop 0] [uncons swap] [dip +] . genrec + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                             23 3 [] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                   23 3 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[] 3 23] [[] =] . infra first choice i + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                              23 3 [] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 3 23] swaack first choice i + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                           23 3 [] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 3 23] swaack first choice i + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                            23 3 True . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 3 23] swaack first choice i + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                        23 3 True [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 3 23] . swaack first choice i + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                        23 3 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [True 3 23] . first choice i + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                               23 3 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] True . choice i + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                      23 3 [] [pop 0] . i + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                              23 3 [] . pop 0 + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                                 23 3 . 0 + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                               23 3 0 . + [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                                 23 3 . [] swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                              23 3 [] . swaack first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                               [3 23] . first [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                                    3 . [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                                                                        3 [[2 []] 23] . [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] infra first [23] swaack sum +
+                                                                                                   3 [[2 []] 23] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] . infra first [23] swaack sum +
+                                                                                                                                                            23 [2 []] . [not] [pop 0] [uncons [] dip i] [map sum +] genrec [3] swaack first [23] swaack sum +
+                                                                                                                                                      23 [2 []] [not] . [pop 0] [uncons [] dip i] [map sum +] genrec [3] swaack first [23] swaack sum +
+                                                                                                                                              23 [2 []] [not] [pop 0] . [uncons [] dip i] [map sum +] genrec [3] swaack first [23] swaack sum +
+                                                                                                                            23 [2 []] [not] [pop 0] [uncons [] dip i] . [map sum +] genrec [3] swaack first [23] swaack sum +
+                                                                                                                23 [2 []] [not] [pop 0] [uncons [] dip i] [map sum +] . genrec [3] swaack first [23] swaack sum +
+                                                             23 [2 []] [not] [pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] . ifte [3] swaack first [23] swaack sum +
+                                                 23 [2 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [[2 []] 23] [not] . infra first choice i [3] swaack first [23] swaack sum +
+                                                                                                                                                            23 [2 []] . not [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [2 []] 23] swaack first choice i [3] swaack first [23] swaack sum +
+                                                                                                                                                             23 False . [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [2 []] 23] swaack first choice i [3] swaack first [23] swaack sum +
+                                                        23 False [[pop 0] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [2 []] 23] . swaack first choice i [3] swaack first [23] swaack sum +
+                                                        23 [2 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] [False 23] . first choice i [3] swaack first [23] swaack sum +
+                                                             23 [2 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] [pop 0] False . choice i [3] swaack first [23] swaack sum +
+                                                                           23 [2 []] [uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum +] . i [3] swaack first [23] swaack sum +
+                                                                                                                                                            23 [2 []] . uncons [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [3] swaack first [23] swaack sum +
+                                                                                                                                                            23 2 [[]] . [] dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [3] swaack first [23] swaack sum +
+                                                                                                                                                         23 2 [[]] [] . dip i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [3] swaack first [23] swaack sum +
+                                                                                                                                                                 23 2 . [[]] i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [3] swaack first [23] swaack sum +
+                                                                                                                                                            23 2 [[]] . i [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [3] swaack first [23] swaack sum +
+                                                                                                                                                                 23 2 . [] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [3] swaack first [23] swaack sum +
+                                                                                                                                                              23 2 [] . [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] map sum + [3] swaack first [23] swaack sum +
+                                                                                                         23 2 [] [[not] [pop 0] [uncons [] dip i] [map sum +] genrec] . map sum + [3] swaack first [23] swaack sum +
+                                                                                                                                                              23 2 [] . sum + [3] swaack first [23] swaack sum +
+                                                                                                                                                              23 2 [] . 0 [+] catamorphism + [3] swaack first [23] swaack sum +
+                                                                                                                                                            23 2 [] 0 . [+] catamorphism + [3] swaack first [23] swaack sum +
+                                                                                                                                                        23 2 [] 0 [+] . catamorphism + [3] swaack first [23] swaack sum +
+                                                                                                                                                        23 2 [] 0 [+] . [[] =] roll> [uncons swap] swap hylomorphism + [3] swaack first [23] swaack sum +
+                                                                                                                                                 23 2 [] 0 [+] [[] =] . roll> [uncons swap] swap hylomorphism + [3] swaack first [23] swaack sum +
+                                                                                                                                                 23 2 [] [[] =] 0 [+] . [uncons swap] swap hylomorphism + [3] swaack first [23] swaack sum +
+                                                                                                                                   23 2 [] [[] =] 0 [+] [uncons swap] . swap hylomorphism + [3] swaack first [23] swaack sum +
+                                                                                                                                   23 2 [] [[] =] 0 [uncons swap] [+] . hylomorphism + [3] swaack first [23] swaack sum +
+                                                                                                                                   23 2 [] [[] =] 0 [uncons swap] [+] . [unit [pop] swoncat] dipd [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                              23 2 [] [[] =] 0 [uncons swap] [+] [unit [pop] swoncat] . dipd [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                                                     23 2 [] [[] =] 0 . unit [pop] swoncat [uncons swap] [+] [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                                                     23 2 [] [[] =] 0 . [] cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                                                  23 2 [] [[] =] 0 [] . cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                                                   23 2 [] [[] =] [0] . [pop] swoncat [uncons swap] [+] [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                                             23 2 [] [[] =] [0] [pop] . swoncat [uncons swap] [+] [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                                             23 2 [] [[] =] [0] [pop] . swap concat [uncons swap] [+] [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                                             23 2 [] [[] =] [pop] [0] . concat [uncons swap] [+] [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                                               23 2 [] [[] =] [pop 0] . [uncons swap] [+] [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                                 23 2 [] [[] =] [pop 0] [uncons swap] . [+] [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                             23 2 [] [[] =] [pop 0] [uncons swap] [+] . [dip] swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                       23 2 [] [[] =] [pop 0] [uncons swap] [+] [dip] . swoncat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                       23 2 [] [[] =] [pop 0] [uncons swap] [+] [dip] . swap concat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                       23 2 [] [[] =] [pop 0] [uncons swap] [dip] [+] . concat genrec + [3] swaack first [23] swaack sum +
+                                                                                                                         23 2 [] [[] =] [pop 0] [uncons swap] [dip +] . genrec + [3] swaack first [23] swaack sum +
+                                                                             23 2 [] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte + [3] swaack first [23] swaack sum +
+                                                                   23 2 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[] 2 23] [[] =] . infra first choice i + [3] swaack first [23] swaack sum +
+                                                                                                                                                              23 2 [] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 2 23] swaack first choice i + [3] swaack first [23] swaack sum +
+                                                                                                                                                           23 2 [] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 2 23] swaack first choice i + [3] swaack first [23] swaack sum +
+                                                                                                                                                            23 2 True . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 2 23] swaack first choice i + [3] swaack first [23] swaack sum +
+                                                                        23 2 True [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 2 23] . swaack first choice i + [3] swaack first [23] swaack sum +
+                                                                        23 2 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [True 2 23] . first choice i + [3] swaack first [23] swaack sum +
+                                                                               23 2 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] True . choice i + [3] swaack first [23] swaack sum +
+                                                                                                                                                      23 2 [] [pop 0] . i + [3] swaack first [23] swaack sum +
+                                                                                                                                                              23 2 [] . pop 0 + [3] swaack first [23] swaack sum +
+                                                                                                                                                                 23 2 . 0 + [3] swaack first [23] swaack sum +
+                                                                                                                                                               23 2 0 . + [3] swaack first [23] swaack sum +
+                                                                                                                                                                 23 2 . [3] swaack first [23] swaack sum +
+                                                                                                                                                             23 2 [3] . swaack first [23] swaack sum +
+                                                                                                                                                             3 [2 23] . first [23] swaack sum +
+                                                                                                                                                                  3 2 . [23] swaack sum +
+                                                                                                                                                             3 2 [23] . swaack sum +
+                                                                                                                                                             23 [2 3] . sum +
+                                                                                                                                                             23 [2 3] . 0 [+] catamorphism +
+                                                                                                                                                           23 [2 3] 0 . [+] catamorphism +
+                                                                                                                                                       23 [2 3] 0 [+] . catamorphism +
+                                                                                                                                                       23 [2 3] 0 [+] . [[] =] roll> [uncons swap] swap hylomorphism +
+                                                                                                                                                23 [2 3] 0 [+] [[] =] . roll> [uncons swap] swap hylomorphism +
+                                                                                                                                                23 [2 3] [[] =] 0 [+] . [uncons swap] swap hylomorphism +
+                                                                                                                                  23 [2 3] [[] =] 0 [+] [uncons swap] . swap hylomorphism +
+                                                                                                                                  23 [2 3] [[] =] 0 [uncons swap] [+] . hylomorphism +
+                                                                                                                                  23 [2 3] [[] =] 0 [uncons swap] [+] . [unit [pop] swoncat] dipd [dip] swoncat genrec +
+                                                                                                             23 [2 3] [[] =] 0 [uncons swap] [+] [unit [pop] swoncat] . dipd [dip] swoncat genrec +
+                                                                                                                                                    23 [2 3] [[] =] 0 . unit [pop] swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                                                                    23 [2 3] [[] =] 0 . [] cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                                                                 23 [2 3] [[] =] 0 [] . cons [pop] swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                                                                  23 [2 3] [[] =] [0] . [pop] swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                                                            23 [2 3] [[] =] [0] [pop] . swoncat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                                                            23 [2 3] [[] =] [0] [pop] . swap concat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                                                            23 [2 3] [[] =] [pop] [0] . concat [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                                                              23 [2 3] [[] =] [pop 0] . [uncons swap] [+] [dip] swoncat genrec +
+                                                                                                                                23 [2 3] [[] =] [pop 0] [uncons swap] . [+] [dip] swoncat genrec +
+                                                                                                                            23 [2 3] [[] =] [pop 0] [uncons swap] [+] . [dip] swoncat genrec +
+                                                                                                                      23 [2 3] [[] =] [pop 0] [uncons swap] [+] [dip] . swoncat genrec +
+                                                                                                                      23 [2 3] [[] =] [pop 0] [uncons swap] [+] [dip] . swap concat genrec +
+                                                                                                                      23 [2 3] [[] =] [pop 0] [uncons swap] [dip] [+] . concat genrec +
+                                                                                                                        23 [2 3] [[] =] [pop 0] [uncons swap] [dip +] . genrec +
+                                                                            23 [2 3] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte +
+                                                                 23 [2 3] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[2 3] 23] [[] =] . infra first choice i +
+                                                                                                                                                             23 [2 3] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [2 3] 23] swaack first choice i +
+                                                                                                                                                          23 [2 3] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [2 3] 23] swaack first choice i +
+                                                                                                                                                             23 False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [2 3] 23] swaack first choice i +
+                                                                        23 False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [2 3] 23] . swaack first choice i +
+                                                                        23 [2 3] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False 23] . first choice i +
+                                                                             23 [2 3] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i +
+                                                                                           23 [2 3] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i +
+                                                                                                                                                             23 [2 3] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + +
+                                                                                                                                                             23 2 [3] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + +
+                                                                                                                                                             23 [3] 2 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + +
+                                                                                                               23 [3] 2 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + +
+                                                                                                                                                               23 [3] . [[] =] [pop 0] [uncons swap] [dip +] genrec 2 + +
+                                                                                                                                                        23 [3] [[] =] . [pop 0] [uncons swap] [dip +] genrec 2 + +
+                                                                                                                                                23 [3] [[] =] [pop 0] . [uncons swap] [dip +] genrec 2 + +
+                                                                                                                                  23 [3] [[] =] [pop 0] [uncons swap] . [dip +] genrec 2 + +
+                                                                                                                          23 [3] [[] =] [pop 0] [uncons swap] [dip +] . genrec 2 + +
+                                                                              23 [3] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 2 + +
+                                                                     23 [3] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[3] 23] [[] =] . infra first choice i 2 + +
+                                                                                                                                                               23 [3] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [3] 23] swaack first choice i 2 + +
+                                                                                                                                                            23 [3] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [3] 23] swaack first choice i 2 + +
+                                                                                                                                                             23 False . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [3] 23] swaack first choice i 2 + +
+                                                                          23 False [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [3] 23] . swaack first choice i 2 + +
+                                                                          23 [3] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [False 23] . first choice i 2 + +
+                                                                               23 [3] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] False . choice i 2 + +
+                                                                                             23 [3] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . i 2 + +
+                                                                                                                                                               23 [3] . uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 2 + +
+                                                                                                                                                              23 3 [] . swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 2 + +
+                                                                                                                                                              23 [] 3 . [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip + 2 + +
+                                                                                                                23 [] 3 [[[] =] [pop 0] [uncons swap] [dip +] genrec] . dip + 2 + +
+                                                                                                                                                                23 [] . [[] =] [pop 0] [uncons swap] [dip +] genrec 3 + 2 + +
+                                                                                                                                                         23 [] [[] =] . [pop 0] [uncons swap] [dip +] genrec 3 + 2 + +
+                                                                                                                                                 23 [] [[] =] [pop 0] . [uncons swap] [dip +] genrec 3 + 2 + +
+                                                                                                                                   23 [] [[] =] [pop 0] [uncons swap] . [dip +] genrec 3 + 2 + +
+                                                                                                                           23 [] [[] =] [pop 0] [uncons swap] [dip +] . genrec 3 + 2 + +
+                                                                               23 [] [[] =] [pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] . ifte 3 + 2 + +
+                                                                       23 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [[] 23] [[] =] . infra first choice i 3 + 2 + +
+                                                                                                                                                                23 [] . [] = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 23] swaack first choice i 3 + 2 + +
+                                                                                                                                                             23 [] [] . = [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 23] swaack first choice i 3 + 2 + +
+                                                                                                                                                              23 True . [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 23] swaack first choice i 3 + 2 + +
+                                                                            23 True [[pop 0] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [] 23] . swaack first choice i 3 + 2 + +
+                                                                            23 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] [True 23] . first choice i 3 + 2 + +
+                                                                                 23 [] [uncons swap [[[] =] [pop 0] [uncons swap] [dip +] genrec] dip +] [pop 0] True . choice i 3 + 2 + +
+                                                                                                                                                        23 [] [pop 0] . i 3 + 2 + +
+                                                                                                                                                                23 [] . pop 0 3 + 2 + +
+                                                                                                                                                                   23 . 0 3 + 2 + +
+                                                                                                                                                                 23 0 . 3 + 2 + +
+                                                                                                                                                               23 0 3 . + 2 + +
+                                                                                                                                                                 23 3 . 2 + +
+                                                                                                                                                               23 3 2 . + +
+                                                                                                                                                                 23 5 . +
+                                                                                                                                                                   28 . 
+
+
+.. code:: ipython2
+
+    J('[23 [[2 [[23 [[2 []] [3 []]]][23 [[2 []] [3 []]]]]] [3 [[23 [[2 []] [3 []]]][23 [[2 []] [3 []]]]]]]] 0 [sum +] [] treestep')
+
+
+.. parsed-literal::
+
+    140
+
+
+.. code:: ipython2
+
+    J('[] [] [unit cons] [23 +] treestep')
+
+
+.. parsed-literal::
+
+    []
+
+
+.. code:: ipython2
+
+    J('[23 []] [] [unit cons] [23 +] treestep')
+
+
+.. parsed-literal::
+
+    [46 []]
+
+
+.. code:: ipython2
+
+    J('[23 [[2 []] [3 []]]] [] [unit cons] [23 +] treestep')
+
+
+.. parsed-literal::
+
+    [46 [[25 []] [26 []]]]
+
+
+.. code:: ipython2
+
+    define('treemap == [] [unit cons] roll< treestep')
+
+.. code:: ipython2
+
+    J('[23 [[2 []] [3 []]]] [23 +] treemap')
+
+
+.. parsed-literal::
+
+    [46 [[25 []] [26 []]]]
+
diff --git a/docs/Newton-Raphson.rst b/docs/Newton-Raphson.rst
new file mode 100644 (file)
index 0000000..7cc23e3
--- /dev/null
@@ -0,0 +1,173 @@
+
+`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
+=====================================================================
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+Cf. `"Why Functional Programming Matters" by John
+Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
+
+:math:`a_{i+1} = \frac{(a_i+\frac{n}{a_i})}{2}`
+
+Let's define a function that computes the above equation:
+
+::
+
+         n a Q
+    ---------------
+       (a+n/a)/2
+
+    n a tuck / + 2 /
+    a n a    / + 2 /
+    a n/a      + 2 /
+    a+n/a        2 /
+    (a+n/a)/2
+
+We want it to leave n but replace a, so we execute it with ``unary``:
+
+::
+
+    Q == [tuck / + 2 /] unary
+
+.. code:: ipython2
+
+    define('Q == [tuck / + 2 /] unary')
+
+And a function to compute the error:
+
+::
+
+    n a sqr - abs
+    |n-a**2|
+
+This should be ``nullary`` so as to leave both n and a on the stack
+below the error.
+
+::
+
+    err == [sqr - abs] nullary
+
+.. code:: ipython2
+
+    define('err == [sqr - abs] nullary')
+
+Now we can define a recursive program that expects a number ``n``, an
+initial estimate ``a``, and an epsilon value ``ε``, and that leaves on
+the stack the square root of ``n`` to within the precision of the
+epsilon value. (Later on we'll refine it to generate the initial
+estimate and hard-code an epsilon value.)
+
+::
+
+    n a ε square-root
+    -----------------
+          √n
+
+If we apply the two functions ``Q`` and ``err`` defined above we get the
+next approximation and the error on the stack below the epsilon.
+
+::
+
+    n a ε [Q err] dip
+    n a Q err ε 
+    n a'  err ε 
+    n a' e    ε
+
+Let's define the recursive function from here. Start with ``ifte``; the
+predicate and the base case behavior are obvious:
+
+::
+
+    n a' e ε [<] [popop popd] [J] ifte
+
+Base-case
+
+::
+
+    n a' e ε popop popd
+    n a'           popd
+      a'
+
+The recursive branch is pretty easy. Discard the error and recur.
+
+::
+
+    w/ K == [<] [popop popd] [J] ifte
+
+    n a' e ε J
+    n a' e ε popd [Q err] dip [K] i
+    n a'   ε      [Q err] dip [K] i
+    n a' Q err ε              [K] i
+    n a''  e   ε               K
+
+This fragment alone is pretty useful.
+
+.. code:: ipython2
+
+    define('K == [<] [popop popd] [popd [Q err] dip] primrec')
+
+.. code:: ipython2
+
+    J('25 10 0.001 dup K')
+
+
+.. parsed-literal::
+
+    5.000000232305737
+
+
+.. code:: ipython2
+
+    J('25 10 0.000001 dup K')
+
+
+.. parsed-literal::
+
+    5.000000000000005
+
+
+So now all we need is a way to generate an initial approximation and an
+epsilon value:
+
+::
+
+    square-root == dup 3 / 0.000001 dup K
+
+.. code:: ipython2
+
+    define('square-root == dup 3 / 0.000001 dup K')
+
+.. code:: ipython2
+
+    J('36 square-root')
+
+
+.. parsed-literal::
+
+    6.000000000000007
+
+
+.. code:: ipython2
+
+    J('4895048365636 square-root')
+
+
+.. parsed-literal::
+
+    2212475.6192184356
+
+
+.. code:: ipython2
+
+    2212475.6192184356 * 2212475.6192184356
+
+
+
+
+.. parsed-literal::
+
+    4895048365636.0
+
+
diff --git a/docs/Quadratic.rst b/docs/Quadratic.rst
new file mode 100644 (file)
index 0000000..1c8b0d5
--- /dev/null
@@ -0,0 +1,180 @@
+
+`Quadratic formula <https://en.wikipedia.org/wiki/Quadratic_formula>`__
+=======================================================================
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+Cf.
+`jp-quadratic.html <http://www.kevinalbrecht.com/code/joy-mirror/jp-quadratic.html>`__
+
+::
+
+             -b  +/- sqrt(b^2 - 4 * a * c)
+             -----------------------------
+                        2 * a
+
+:math:`\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}`
+
+Write a straightforward program with variable names.
+====================================================
+
+::
+
+    b neg b sqr 4 a c * * - sqrt [+] [-] cleave a 2 * [truediv] cons app2
+
+Check it.
+~~~~~~~~~
+
+::
+
+     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
+
+Codicil
+~~~~~~~
+
+::
+
+    -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
+
+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:
+
+.. code:: ipython2
+
+    define('pm == [+] [-] cleave popdd')
+
+Then ``quadratic`` becomes:
+
+.. code:: ipython2
+
+    define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [truediv] cons app2')
+
+.. code:: ipython2
+
+    J('3 1 1 quadratic')
+
+
+.. parsed-literal::
+
+    -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.
+
+.. code:: ipython2
+
+    from joy.library import SimpleFunctionWrapper
+    from notebook_preamble import D
+    
+    
+    @SimpleFunctionWrapper
+    def pm(stack):
+        a, (b, stack) = stack
+        p, m, = b + a, b - a
+        return m, (p, stack)
+    
+    
+    D['pm'] = pm
+
+The resulting trace is short enough to fit on a page.
+
+.. code:: ipython2
+
+    V('3 1 1 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 . 
+
diff --git a/docs/Trees.rst b/docs/Trees.rst
new file mode 100644 (file)
index 0000000..06bd719
--- /dev/null
@@ -0,0 +1,1795 @@
+
+Treating 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.
+
+The basic structure, in a `crude type
+notation <https://en.wikipedia.org/wiki/Algebraic_data_type>`__, is:
+
+::
+
+    BTree :: [] | [key value BTree BTree]
+
+That says that a BTree is either the empty quote ``[]`` or a quote with
+four items: a key, a value, and two BTrees representing the left and
+right branches of the tree.
+
+A Function to Traverse this Structure
+-------------------------------------
+
+Let's take a crack at writing a function that can recursively iterate or
+traverse these trees.
+
+Base case ``[]``
+^^^^^^^^^^^^^^^^
+
+The stopping predicate just has to detect the empty list:
+
+::
+
+    BTree-iter == [not] [E] [R0] [R1] genrec
+
+And since there's nothing at this node, we just ``pop`` it:
+
+::
+
+    BTree-iter == [not] [pop] [R0] [R1] genrec
+
+Node case ``[key value left right]``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Now we need to figure out ``R0`` and ``R1``:
+
+::
+
+    BTree-iter == [not] [pop] [R0]            [R1] genrec
+               == [not] [pop] [R0 [BTree-iter] R1] ifte
+
+Let's look at it *in situ*:
+
+::
+
+    [key value left right] R0 [BTree-iter] R1
+
+Processing the current node.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``R0`` is almost certainly going to use ``dup`` to make a copy of the
+node and then ``dip`` on some function to process the copy with it:
+
+::
+
+    [key value left right] [F] dupdip                 [BTree-iter] R1
+    [key value left right]  F  [key value left right] [BTree-iter] R1
+
+For example, if we're getting all the keys ``F`` would be ``first``:
+
+::
+
+    R0 == [first] dupdip
+
+    [key value left right] [first] dupdip                 [BTree-iter] R1
+    [key value left right]  first  [key value left right] [BTree-iter] R1
+    key                            [key value left right] [BTree-iter] R1
+
+Recur
+^^^^^
+
+Now ``R1`` needs to apply ``[BTree-iter]`` to ``left`` and ``right``. If
+we drop the key and value from the node using ``rest`` twice we are left
+with an interesting situation:
+
+::
+
+    key [key value left right] [BTree-iter] R1
+    key [key value left right] [BTree-iter] [rest rest] dip
+    key [key value left right] rest rest [BTree-iter]
+    key [left right] [BTree-iter]
+
+Hmm, will ``step`` do?
+
+::
+
+    key [left right] [BTree-iter] step
+    key left BTree-iter [right] [BTree-iter] step
+    key left-keys [right] [BTree-iter] step
+    key left-keys right BTree-iter
+    key left-keys right-keys
+
+Wow. So:
+
+::
+
+    R1 == [rest rest] dip step
+
+Putting it together
+^^^^^^^^^^^^^^^^^^^
+
+We have:
+
+::
+
+    BTree-iter == [not] [pop] [[F] dupdip] [[rest rest] dip step] genrec
+
+When I was reading this over I realized ``rest rest`` could go in
+``R0``:
+
+::
+
+    BTree-iter == [not] [pop] [[F] dupdip rest rest] [step] genrec
+
+(And ``[step] genrec`` is such a cool and suggestive combinator!)
+
+Parameterizing the ``F`` per-node processing function.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    [F] BTree-iter == [not] [pop] [[F] dupdip rest rest] [step] genrec
+
+Working backward:
+
+::
+
+    [not] [pop] [[F] dupdip rest rest]            [step] genrec
+    [not] [pop] [F]       [dupdip rest rest] cons [step] genrec
+    [F] [not] [pop] roll< [dupdip rest rest] cons [step] genrec
+
+Ergo:
+
+::
+
+    BTree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+.. code:: ipython2
+
+    define('BTree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec')
+
+.. code:: ipython2
+
+    J('[] [23] BTree-iter')  #  It doesn't matter what F is as it won't be used.
+
+
+.. parsed-literal::
+
+    
+
+
+.. code:: ipython2
+
+    J('["tommy" 23 [] []] [first] BTree-iter')
+
+
+.. parsed-literal::
+
+    'tommy'
+
+
+.. code:: ipython2
+
+    J('["tommy" 23 ["richard" 48 [] []] ["jenny" 18 [] []]] [first] BTree-iter')
+
+
+.. parsed-literal::
+
+    'tommy' 'richard' 'jenny'
+
+
+.. code:: ipython2
+
+    J('["tommy" 23 ["richard" 48 [] []] ["jenny" 18 [] []]] [second] BTree-iter')
+
+
+.. parsed-literal::
+
+    23 48 18
+
+
+Adding Nodes to the BTree
+=========================
+
+Let's consider adding nodes to a BTree structure.
+
+::
+
+    BTree value key BTree-add == BTree
+
+Adding to an empty node.
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+If the current node is ``[]`` then you just return
+``[key value [] []]``:
+
+::
+
+    BTree-add == [popop not] [[pop] dipd BTree-new] [R0] [R1] genrec
+
+Where ``BTree-new`` is:
+
+::
+
+    value key BTree-new == [key value [] []]
+
+    value key swap [[] []] cons cons
+    key value      [[] []] cons cons
+    key      [value [] []]      cons
+         [key value [] []]
+
+    BTree-new == swap [[] []] cons cons
+
+.. code:: ipython2
+
+    define('BTree-new == swap [[] []] cons cons')
+
+.. code:: ipython2
+
+    V('"v" "k" BTree-new')
+
+
+.. parsed-literal::
+
+                    . 'v' 'k' BTree-new
+                'v' . 'k' BTree-new
+            'v' 'k' . BTree-new
+            'v' 'k' . swap [[] []] cons cons
+            'k' 'v' . [[] []] cons cons
+    'k' 'v' [[] []] . cons cons
+    'k' ['v' [] []] . cons
+    ['k' 'v' [] []] . 
+
+
+(As an implementation detail, the ``[[] []]`` literal used in the
+definition of ``BTree-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 ``BTree-new``, all new nodes can
+reuse it as their own tail without fear that some other code somewhere
+will change it.)
+
+If the current node isn't empty.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We now have to derive ``R0`` and ``R1``, consider:
+
+::
+
+    [key_n value_n left right] value key R0 [BTree-add] R1
+
+In this case, there are three possibilites: the key can be greater or
+less than or equal to the node's key. In two of those cases we will need
+to apply a copy of ``BTree-add``, so ``R0`` is pretty much out of the
+picture.
+
+::
+
+    [R0] == []
+
+A predicate to compare keys.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The first thing we need to do is compare the the key we're adding to see
+if it is greater than the node key and ``branch`` accordingly, although
+in this case it's easier to write a destructive predicate and then use
+``ifte`` to apply it ``nullary``:
+
+::
+
+    [key_n value_n left right] value key [BTree-add] R1
+    [key_n value_n left right] value key [BTree-add] [P >] [T] [E] ifte
+
+    [key_n value_n left right] value key [BTree-add] P                   >
+    [key_n value_n left right] value key [BTree-add] pop roll> pop first >
+    [key_n value_n left right] value key                 roll> pop first >
+    key [key_n value_n left right] value                 roll> pop first >
+    key key_n                                                            >
+    Boolean
+
+    P > == pop roll> pop first >
+    P < == pop roll> pop first <
+    P   == pop roll> pop first
+
+.. code:: ipython2
+
+    define('P == pop roll> pop first')
+
+.. code:: ipython2
+
+    V('["k" "v" [] []] "vv" "kk" [0] P >')
+
+
+.. parsed-literal::
+
+                                  . ['k' 'v' [] []] 'vv' 'kk' [0] P >
+                  ['k' 'v' [] []] . 'vv' 'kk' [0] P >
+             ['k' 'v' [] []] 'vv' . 'kk' [0] P >
+        ['k' 'v' [] []] 'vv' 'kk' . [0] P >
+    ['k' 'v' [] []] 'vv' 'kk' [0] . P >
+    ['k' 'v' [] []] 'vv' 'kk' [0] . pop roll> pop first >
+        ['k' 'v' [] []] 'vv' 'kk' . roll> pop first >
+        'kk' ['k' 'v' [] []] 'vv' . pop first >
+             'kk' ['k' 'v' [] []] . first >
+                         'kk' 'k' . >
+                             True . 
+
+
+If the key we're adding is greater than the node's key.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Here the parantheses are meant to signify that the right-hand side (RHS)
+is not literal, the code in the parentheses is meant to have been
+evaluated:
+
+::
+
+    [key_n value_n left right] value key [BTree-add] T == [key_n value_n left (BTree-add key value right)]
+
+Use ``infra`` on ``K``.
+^^^^^^^^^^^^^^^^^^^^^^^
+
+So how do we do this? We know we're going to want to use ``infra`` on
+some function ``K`` that has the key and value to work with, as well as
+the quoted copy of ``BTree-add`` to apply somehow:
+
+::
+
+    right left value_n key_n value key [BTree-add] K
+        ...
+    right value key BTree-add left value_n key_n
+
+Pretty easy:
+
+::
+
+    right left value_n key_n value key [BTree-add] cons cons dipdd
+    right left value_n key_n [value key BTree-add]           dipdd
+    right value key BTree-add left value_n key_n
+
+So:
+
+::
+
+    K == cons cons dipdd
+
+And:
+
+::
+
+    [key_n value_n left right] [value key [BTree-add] K] infra
+
+Derive ``T``.
+^^^^^^^^^^^^^
+
+So now we're at getting from this to this:
+
+::
+
+    [key_n value_n left right]  value key [BTree-add] T
+        ...
+    [key_n value_n left right] [value key [BTree-add] K] infra
+
+And so ``T`` is just:
+
+::
+
+    value key [BTree-add] T == [value key [BTree-add] K]                infra
+                          T == [                      K] cons cons cons infra
+
+.. code:: ipython2
+
+    define('K == cons cons dipdd')
+    define('T == [K] cons cons cons infra')
+
+.. code:: ipython2
+
+    V('"r" "l" "v" "k" "vv" "kk" [0] K')
+
+
+.. parsed-literal::
+
+                                  . 'r' 'l' 'v' 'k' 'vv' 'kk' [0] K
+                              'r' . 'l' 'v' 'k' 'vv' 'kk' [0] K
+                          'r' 'l' . 'v' 'k' 'vv' 'kk' [0] K
+                      'r' 'l' 'v' . 'k' 'vv' 'kk' [0] K
+                  'r' 'l' 'v' 'k' . 'vv' 'kk' [0] K
+             'r' 'l' 'v' 'k' 'vv' . 'kk' [0] K
+        'r' 'l' 'v' 'k' 'vv' 'kk' . [0] K
+    'r' 'l' 'v' 'k' 'vv' 'kk' [0] . K
+    'r' 'l' 'v' 'k' 'vv' 'kk' [0] . cons cons dipdd
+    'r' 'l' 'v' 'k' 'vv' ['kk' 0] . cons dipdd
+    'r' 'l' 'v' 'k' ['vv' 'kk' 0] . dipdd
+                              'r' . 'vv' 'kk' 0 'l' 'v' 'k'
+                         'r' 'vv' . 'kk' 0 'l' 'v' 'k'
+                    'r' 'vv' 'kk' . 0 'l' 'v' 'k'
+                  'r' 'vv' 'kk' 0 . 'l' 'v' 'k'
+              'r' 'vv' 'kk' 0 'l' . 'v' 'k'
+          'r' 'vv' 'kk' 0 'l' 'v' . 'k'
+      'r' 'vv' 'kk' 0 'l' 'v' 'k' . 
+
+
+.. code:: ipython2
+
+    V('["k" "v" "l" "r"] "vv" "kk" [0] T')
+
+
+.. parsed-literal::
+
+                                        . ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] T
+                      ['k' 'v' 'l' 'r'] . 'vv' 'kk' [0] T
+                 ['k' 'v' 'l' 'r'] 'vv' . 'kk' [0] T
+            ['k' 'v' 'l' 'r'] 'vv' 'kk' . [0] T
+        ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] . T
+        ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] . [K] cons cons cons infra
+    ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] [K] . cons cons cons infra
+    ['k' 'v' 'l' 'r'] 'vv' 'kk' [[0] K] . cons cons infra
+    ['k' 'v' 'l' 'r'] 'vv' ['kk' [0] K] . cons infra
+    ['k' 'v' 'l' 'r'] ['vv' 'kk' [0] K] . infra
+                        'r' 'l' 'v' 'k' . 'vv' 'kk' [0] K [] swaack
+                   'r' 'l' 'v' 'k' 'vv' . 'kk' [0] K [] swaack
+              'r' 'l' 'v' 'k' 'vv' 'kk' . [0] K [] swaack
+          'r' 'l' 'v' 'k' 'vv' 'kk' [0] . K [] swaack
+          'r' 'l' 'v' 'k' 'vv' 'kk' [0] . cons cons dipdd [] swaack
+          'r' 'l' 'v' 'k' 'vv' ['kk' 0] . cons dipdd [] swaack
+          'r' 'l' 'v' 'k' ['vv' 'kk' 0] . dipdd [] swaack
+                                    'r' . 'vv' 'kk' 0 'l' 'v' 'k' [] swaack
+                               'r' 'vv' . 'kk' 0 'l' 'v' 'k' [] swaack
+                          'r' 'vv' 'kk' . 0 'l' 'v' 'k' [] swaack
+                        'r' 'vv' 'kk' 0 . 'l' 'v' 'k' [] swaack
+                    'r' 'vv' 'kk' 0 'l' . 'v' 'k' [] swaack
+                'r' 'vv' 'kk' 0 'l' 'v' . 'k' [] swaack
+            'r' 'vv' 'kk' 0 'l' 'v' 'k' . [] swaack
+         'r' 'vv' 'kk' 0 'l' 'v' 'k' [] . swaack
+          ['k' 'v' 'l' 0 'kk' 'vv' 'r'] . 
+
+
+If the key we're adding is less than the node's key.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This is very very similar to the above:
+
+::
+
+    [key_n value_n left right] value key [BTree-add] E
+    [key_n value_n left right] value key [BTree-add] [P <] [Te] [Ee] ifte
+
+In this case ``Te`` works that same as ``T`` but on the left child tree
+instead of the right, so the only difference is that it must use
+``dipd`` instead of ``dipdd``:
+
+::
+
+    Te == [cons cons dipd] cons cons cons infra
+
+This suggests an alternate factorization:
+
+::
+
+    ccons == cons cons
+    T == [ccons dipdd] ccons cons infra
+    Te == [ccons dipd] ccons cons infra
+
+But whatever.
+
+.. code:: ipython2
+
+    define('Te == [cons cons dipd] cons cons cons infra')
+
+.. code:: ipython2
+
+    V('["k" "v" "l" "r"] "vv" "kk" [0] Te')
+
+
+.. parsed-literal::
+
+                                                     . ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] Te
+                                   ['k' 'v' 'l' 'r'] . 'vv' 'kk' [0] Te
+                              ['k' 'v' 'l' 'r'] 'vv' . 'kk' [0] Te
+                         ['k' 'v' 'l' 'r'] 'vv' 'kk' . [0] Te
+                     ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] . Te
+                     ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] . [cons cons dipd] cons cons cons infra
+    ['k' 'v' 'l' 'r'] 'vv' 'kk' [0] [cons cons dipd] . cons cons cons infra
+    ['k' 'v' 'l' 'r'] 'vv' 'kk' [[0] cons cons dipd] . cons cons infra
+    ['k' 'v' 'l' 'r'] 'vv' ['kk' [0] cons cons dipd] . cons infra
+    ['k' 'v' 'l' 'r'] ['vv' 'kk' [0] cons cons dipd] . infra
+                                     'r' 'l' 'v' 'k' . 'vv' 'kk' [0] cons cons dipd [] swaack
+                                'r' 'l' 'v' 'k' 'vv' . 'kk' [0] cons cons dipd [] swaack
+                           'r' 'l' 'v' 'k' 'vv' 'kk' . [0] cons cons dipd [] swaack
+                       'r' 'l' 'v' 'k' 'vv' 'kk' [0] . cons cons dipd [] swaack
+                       'r' 'l' 'v' 'k' 'vv' ['kk' 0] . cons dipd [] swaack
+                       'r' 'l' 'v' 'k' ['vv' 'kk' 0] . dipd [] swaack
+                                             'r' 'l' . 'vv' 'kk' 0 'v' 'k' [] swaack
+                                        'r' 'l' 'vv' . 'kk' 0 'v' 'k' [] swaack
+                                   'r' 'l' 'vv' 'kk' . 0 'v' 'k' [] swaack
+                                 'r' 'l' 'vv' 'kk' 0 . 'v' 'k' [] swaack
+                             'r' 'l' 'vv' 'kk' 0 'v' . 'k' [] swaack
+                         'r' 'l' 'vv' 'kk' 0 'v' 'k' . [] swaack
+                      'r' 'l' 'vv' 'kk' 0 'v' 'k' [] . swaack
+                       ['k' 'v' 0 'kk' 'vv' 'l' 'r'] . 
+
+
+Else the keys must be equal.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This means we must find:
+
+::
+
+    [key_n value_n left right] value key [BTree-add] Ee
+        ...
+    [key value left right]
+
+This is another easy one:
+
+::
+
+    Ee == pop swap roll< rest rest cons cons
+
+    [key_n value_n left right] value key [BTree-add] pop swap roll< rest rest cons cons
+    [key_n value_n left right] value key                 swap roll< rest rest cons cons
+    [key_n value_n left right] key value                      roll< rest rest cons cons
+    key value [key_n value_n left right]                            rest rest cons cons
+    key value [              left right]                                      cons cons
+              [key   value   left right]
+
+.. code:: ipython2
+
+    define('Ee == pop swap roll< rest rest cons cons')
+
+.. code:: ipython2
+
+    V('["k" "v" "l" "r"] "vv" "k" [0] Ee')
+
+
+.. parsed-literal::
+
+                                   . ['k' 'v' 'l' 'r'] 'vv' 'k' [0] Ee
+                 ['k' 'v' 'l' 'r'] . 'vv' 'k' [0] Ee
+            ['k' 'v' 'l' 'r'] 'vv' . 'k' [0] Ee
+        ['k' 'v' 'l' 'r'] 'vv' 'k' . [0] Ee
+    ['k' 'v' 'l' 'r'] 'vv' 'k' [0] . Ee
+    ['k' 'v' 'l' 'r'] 'vv' 'k' [0] . pop swap roll< rest rest cons cons
+        ['k' 'v' 'l' 'r'] 'vv' 'k' . swap roll< rest rest cons cons
+        ['k' 'v' 'l' 'r'] 'k' 'vv' . roll< rest rest cons cons
+        'k' 'vv' ['k' 'v' 'l' 'r'] . rest rest cons cons
+            'k' 'vv' ['v' 'l' 'r'] . rest cons cons
+                'k' 'vv' ['l' 'r'] . cons cons
+                'k' ['vv' 'l' 'r'] . cons
+                ['k' 'vv' 'l' 'r'] . 
+
+
+.. code:: ipython2
+
+    define('E == [P <] [Te] [Ee] ifte')
+
+Now we can define ``BTree-add``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    BTree-add == [popop not] [[pop] dipd BTree-new] [] [[P >] [T] [E] ifte] genrec
+
+Putting it all together:
+
+::
+
+    BTree-new == swap [[] []] cons cons
+    P == pop roll> pop first
+    T == [cons cons dipdd] cons cons cons infra
+    Te == [cons cons dipd] cons cons cons infra
+    Ee == pop swap roll< rest rest cons cons
+    E == [P <] [Te] [Ee] ifte
+
+    BTree-add == [popop not] [[pop] dipd BTree-new] [] [[P >] [T] [E] ifte] genrec
+
+.. code:: ipython2
+
+    define('BTree-add == [popop not] [[pop] dipd BTree-new] [] [[P >] [T] [E] ifte] genrec')
+
+.. code:: ipython2
+
+    J('[] 23 "b" BTree-add')  # Initial
+
+
+.. parsed-literal::
+
+    ['b' 23 [] []]
+
+
+.. code:: ipython2
+
+    J('["b" 23 [] []] 88 "c" BTree-add')  # Less than
+
+
+.. parsed-literal::
+
+    ['b' 23 [] ['c' 88 [] []]]
+
+
+.. code:: ipython2
+
+    J('["b" 23 [] []] 88 "a" BTree-add')  # Greater than
+
+
+.. parsed-literal::
+
+    ['b' 23 ['a' 88 [] []] []]
+
+
+.. code:: ipython2
+
+    J('["b" 23 [] []] 88 "b" BTree-add')  # Equal to
+
+
+.. parsed-literal::
+
+    ['b' 88 [] []]
+
+
+.. code:: ipython2
+
+    J('[] 23 "a" BTree-add 88 "b" BTree-add 44 "c" BTree-add')  # Series.
+
+
+.. parsed-literal::
+
+    ['a' 23 [] ['b' 88 [] ['c' 44 [] []]]]
+
+
+We can use this to make a set-like datastructure by just setting values
+to e.g. 0 and ignoring them. It's set-like in that duplicate items added
+to it will only occur once within it, and we can query it in
+`:math:`O(\log_2 N)` <https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2>`__
+time.
+
+.. code:: ipython2
+
+    J('[] [3 9 5 2 8 6 7 8 4] [0 swap BTree-add] step')
+
+
+.. parsed-literal::
+
+    [3 0 [2 0 [] []] [9 0 [5 0 [4 0 [] []] [8 0 [6 0 [] [7 0 [] []]] []]] []]]
+
+
+.. code:: ipython2
+
+    define('to_set == [] swap [0 swap BTree-add] step')
+
+.. code:: ipython2
+
+    J('[3 9 5 2 8 6 7 8 4] to_set')
+
+
+.. parsed-literal::
+
+    [3 0 [2 0 [] []] [9 0 [5 0 [4 0 [] []] [8 0 [6 0 [] [7 0 [] []]] []]] []]]
+
+
+And with that we can write a little program to remove duplicate items
+from a list.
+
+.. code:: ipython2
+
+    define('unique == [to_set [first] BTree-iter] cons run')
+
+.. code:: ipython2
+
+    J('[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique')  # Filter duplicate items.
+
+
+.. parsed-literal::
+
+    [7 6 8 4 5 9 2 3]
+
+
+``cmp`` combinator
+==================
+
+Instead of all this mucking about with nested ``ifte`` 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:
+
+::
+
+       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
+
+We need a new non-destructive predicate ``P``:
+
+::
+
+    [key_n value_n left right] value key [BTree-add] P
+    [key_n value_n left right] value key [BTree-add] over [Q] nullary
+    [key_n value_n left right] value key [BTree-add] key  [Q] nullary
+    [key_n value_n left right] value key [BTree-add] key   Q
+    [key_n value_n left right] value key [BTree-add] key   popop popop first
+    [key_n value_n left right] value key                         popop first
+    [key_n value_n left right]                                         first
+     key_n
+    [key_n value_n left right] value key [BTree-add] key  [Q] nullary
+    [key_n value_n left right] value key [BTree-add] key key_n
+
+    P == over [popop popop first] nullary
+
+Here are the definitions again, pruned and renamed in some cases:
+
+::
+
+    BTree-new == swap [[] []] cons cons
+    P == over [popop popop first] nullary
+    T> == [cons cons dipdd] cons cons cons infra
+    T< == [cons cons dipd] cons cons cons infra
+    E == pop swap roll< rest rest cons cons
+
+Using ``cmp`` to simplify `our code above at
+``R1`` <#If-the-current-node-isn't-empty.>`__:
+
+::
+
+    [key_n value_n left right] value key [BTree-add] R1
+    [key_n value_n left right] value key [BTree-add] P [T>] [E] [T<] cmp
+
+The line above becomes one of the three lines below:
+
+::
+
+    [key_n value_n left right] value key [BTree-add] T>
+    [key_n value_n left right] value key [BTree-add] E
+    [key_n value_n left right] value key [BTree-add] T<
+
+The definition is a little longer but, I think, more elegant and easier
+to understand:
+
+::
+
+    BTree-add == [popop not] [[pop] dipd BTree-new] [] [P [T>] [E] [T<] cmp] genrec
+
+.. code:: ipython2
+
+    from joy.library import FunctionWrapper
+    from joy.utils.stack import pushback
+    from notebook_preamble import D
+    
+    
+    @FunctionWrapper
+    def cmp_(stack, expression, dictionary):
+        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")
+
+
+.. parsed-literal::
+
+    'G'
+
+
+.. code:: ipython2
+
+    J("1 1 ['G'] ['E'] ['L'] cmp")
+
+
+.. parsed-literal::
+
+    'E'
+
+
+.. code:: ipython2
+
+    J("0 1 ['G'] ['E'] ['L'] cmp")
+
+
+.. parsed-literal::
+
+    'L'
+
+
+.. code:: ipython2
+
+    from joy.library import DefinitionWrapper
+    
+    
+    DefinitionWrapper.add_definitions('''
+    
+    P == over [popop popop first] nullary
+    T> == [cons cons dipdd] cons cons cons infra
+    T< == [cons cons dipd] cons cons cons infra
+    E == pop swap roll< rest rest cons cons
+    
+    BTree-add == [popop not] [[pop] dipd BTree-new] [] [P [T>] [E] [T<] cmp] genrec
+    
+    ''', D)
+
+.. code:: ipython2
+
+    J('[] 23 "b" BTree-add')  # Initial
+
+
+.. parsed-literal::
+
+    ['b' 23 [] []]
+
+
+.. code:: ipython2
+
+    J('["b" 23 [] []] 88 "c" BTree-add')  # Less than
+
+
+.. parsed-literal::
+
+    ['b' 23 [] ['c' 88 [] []]]
+
+
+.. code:: ipython2
+
+    J('["b" 23 [] []] 88 "a" BTree-add')  # Greater than
+
+
+.. parsed-literal::
+
+    ['b' 23 ['a' 88 [] []] []]
+
+
+.. code:: ipython2
+
+    J('["b" 23 [] []] 88 "b" BTree-add')  # Equal to
+
+
+.. parsed-literal::
+
+    ['b' 88 [] []]
+
+
+.. code:: ipython2
+
+    J('[] 23 "a" BTree-add 88 "b" BTree-add 44 "c" BTree-add')  # Series.
+
+
+.. parsed-literal::
+
+    ['a' 23 [] ['b' 88 [] ['c' 44 [] []]]]
+
+
+Factoring and naming
+====================
+
+It may seem silly, but a big part of programming in Forth (and therefore
+in Joy) is the idea of small, highly-factored definitions. If you choose
+names carefully the resulting definitions can take on a semantic role.
+
+::
+
+    get-node-key == popop popop first
+    remove-key-and-value-from-node == rest rest
+    pack-key-and-value == cons cons
+    prep-new-key-and-value == pop swap roll<
+    pack-and-apply == [pack-key-and-value] swoncat cons pack-key-and-value infra
+
+    BTree-new == swap [[] []] pack-key-and-value
+    P == over [get-node-key] nullary
+    T> == [dipdd] pack-and-apply
+    T< == [dipd] pack-and-apply
+    E == prep-new-key-and-value remove-key-and-value-from-node pack-key-and-value
+
+A Version of ``BTree-iter`` that does In-Order Traversal
+========================================================
+
+If you look back to the `non-empty case of the ``BTree-iter``
+function <#Node-case-%5Bkey-value-left-right%5D>`__ we can design a
+varient that first processes the left child, then the current node, then
+the right child. This will allow us to traverse the tree in sort order.
+
+::
+
+    BTree-iter-order == [not] [pop] [R0 [BTree-iter] R1] ifte
+
+To define ``R0`` and ``R1`` it helps to look at them as they will appear
+when they run:
+
+::
+
+    [key value left right] R0 [BTree-iter-order] R1
+
+Process the left child.
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Staring at this for a bit suggests ``dup third`` to start:
+
+::
+
+    [key value left right] R0        [BTree-iter-order] R1
+    [key value left right] dup third [BTree-iter-order] R1
+    [key value left right] left      [BTree-iter-order] R1
+
+Now maybe:
+
+::
+
+    [key value left right] left [BTree-iter-order] [cons dip] dupdip
+    [key value left right] left [BTree-iter-order] cons dip [BTree-iter-order]
+    [key value left right] [left BTree-iter-order]      dip [BTree-iter-order]
+    left BTree-iter-order [key value left right]            [BTree-iter-order]
+
+Process the current node.
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+So far, so good. Now we need to process the current node's values:
+
+::
+
+    left BTree-iter-order [key value left right] [BTree-iter-order] [[F] dupdip] dip
+    left BTree-iter-order [key value left right] [F] dupdip [BTree-iter-order]
+    left BTree-iter-order [key value left right] F [key value left right] [BTree-iter-order]
+
+If ``F`` needs items from the stack below the left stuff it should have
+``cons``'d them before beginning maybe? For functions like ``first`` it
+works fine as-is.
+
+::
+
+    left BTree-iter-order [key value left right] first [key value left right] [BTree-iter-order]
+    left BTree-iter-order key [key value left right] [BTree-iter-order]
+
+Process the right child.
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+First ditch the rest of the node and get the right child:
+
+::
+
+    left BTree-iter-order key [key value left right] [BTree-iter-order] [rest rest rest first] dip
+    left BTree-iter-order key right [BTree-iter-order]
+
+Then, of course, we just need ``i`` to run ``BTree-iter-order`` on the
+right side:
+
+::
+
+    left BTree-iter-order key right [BTree-iter-order] i
+    left BTree-iter-order key right BTree-iter-order
+
+Defining ``BTree-iter-order``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The result is a little awkward:
+
+::
+
+    R1 == [cons dip] dupdip [[F] dupdip] dip [rest rest rest first] dip i
+
+Let's do a little semantic factoring:
+
+::
+
+    fourth == rest rest rest first
+
+    proc_left == [cons dip] dupdip
+    proc_current == [[F] dupdip] dip
+    proc_right == [fourth] dip i
+
+    BTree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] genrec
+
+Now we can sort sequences.
+
+.. code:: ipython2
+
+    define('BTree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')
+
+.. code:: ipython2
+
+    J('[3 9 5 2 8 6 7 8 4] to_set BTree-iter-order')
+
+
+.. parsed-literal::
+
+    2 3 4 5 6 7 8 9
+
+
+Getting values by key
+=====================
+
+Let's derive a function that accepts a tree and a key and returns the
+value associated with that key.
+
+::
+
+       tree key BTree-get
+    ------------------------
+            value
+
+The base case ``[]``
+^^^^^^^^^^^^^^^^^^^^
+
+As before, the stopping predicate just has to detect the empty list:
+
+::
+
+    BTree-get == [pop not] [E] [R0] [R1] genrec
+
+But what do we do if the key isn't in the tree? In Python we might raise
+a ``KeyError`` but I'd like to avoid exceptions in Joy if possible, and
+here I think it's possible. (Division by zero is an example of where I
+think it's probably better to let Python crash Joy. Sometimes the
+machinery fails and you have to "stop the line", methinks.)
+
+Let's pass the buck to the caller by making the base case a given, you
+have to decide for yourself what ``[E]`` should be.
+
+::
+
+       tree key [E] BTree-get
+    ---------------------------- key in tree
+               value
+
+       tree key [E] BTree-get
+    ---------------------------- key not in tree
+             tree key E
+
+Now we define:
+
+::
+
+    BTree-get == [pop not] swap [R0] [R1] genrec
+
+Note that this ``BTree-get`` creates a slightly different function than
+itself and *that function* does the actual recursion. This kind of
+higher-level programming is unusual in most languages but natural in
+Joy.
+
+::
+
+    tree key [E] [pop not] swap [R0] [R1] genrec
+    tree key [pop not] [E] [R0] [R1] genrec
+
+The anonymous specialized recursive function that will do the real work.
+
+::
+
+    [pop not] [E] [R0] [R1] genrec
+
+Node case ``[key value left right]``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Now we need to figure out ``R0`` and ``R1``:
+
+::
+
+    [key value left right] key R0 [BTree-get] R1
+
+We want to compare the search key with the key in the node, and if they
+are the same return the value and if they differ then recurse on one of
+the child nodes. So it's very similar to the above funtion, with
+``[R0] == []`` and ``R1 == P [T>] [E] [T<] cmp``:
+
+::
+
+    [key value left right] key [BTree-get] P [T>] [E] [T<] cmp
+
+So:
+
+::
+
+    get-node-key == pop popop first
+    P == over [get-node-key] nullary
+
+The only difference is that ``get-node-key`` does one less ``pop``
+because there's no value to discard. Now we have to derive the branches:
+
+::
+
+    [key_n value_n left right] key [BTree-get] T>
+    [key_n value_n left right] key [BTree-get] E
+    [key_n value_n left right] key [BTree-get] T<
+
+The cases of ``T>`` and ``T<`` are similar to above but instead of using
+``infra`` we have to discard the rest of the structure:
+
+::
+
+    [key_n value_n left right] key [BTree-get] T> == right key BTree-get
+    [key_n value_n left right] key [BTree-get] T< == left key BTree-get
+
+So:
+
+::
+
+    T> == [fourth] dipd i
+    T< == [third] dipd i
+
+E.g.:
+
+::
+
+    [key_n value_n left right]        key [BTree-get] [fourth] dipd i
+    [key_n value_n left right] fourth key [BTree-get]               i
+                        right         key [BTree-get]               i
+                        right         key  BTree-get
+
+And:
+
+::
+
+    [key_n value_n left right] key [BTree-get] E == value_n
+
+    E == popop second
+
+So:
+
+::
+
+    fourth == rest rest rest first
+    get-node-key == pop popop first
+    P == over [get-node-key] nullary
+    T> == [fourth] dipd i
+    T< == [third] dipd i
+    E == popop second
+
+    BTree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
+
+.. code:: ipython2
+
+    # I don't want to deal with name conflicts with the above so I'm inlining everything here.
+    # The original Joy system has "hide" which is a meta-command which allows you to use named
+    # definitions that are only in scope for a given definition.  I don't want to implement
+    # that (yet) so...
+    
+    
+    define('''
+    BTree-get == [pop not] swap [] [
+      over [pop popop first] nullary
+      [[rest rest rest first] dipd i]
+      [popop second]
+      [[third] dipd i]
+      cmp
+      ] genrec
+    ''')
+
+.. code:: ipython2
+
+    J('[] "gary" [popop "err"] BTree-get')
+
+
+.. parsed-literal::
+
+    'err'
+
+
+.. code:: ipython2
+
+    J('["gary" 23 [] []] "gary" [popop "err"] BTree-get')
+
+
+.. parsed-literal::
+
+    23
+
+
+.. code:: ipython2
+
+    J('''
+    
+        [] [[0 'a'] [1 'b'] [2 'c']] [i BTree-add] step
+    
+        'c' [popop 'not found'] BTree-get
+    
+    ''')
+
+
+.. parsed-literal::
+
+    2
+
+
+TODO: BTree-delete
+==================
+
+Then, once we have add, get, and delete we can see about abstracting
+them.
+
+::
+
+       tree key [E] BTree-delete
+    ---------------------------- key in tree
+           tree
+
+       tree key [E] BTree-delete
+    ---------------------------- key not in tree
+             tree key E
+
+So:
+
+::
+
+    BTree-delete == [pop not] [] [R0] [R1] genrec
+
+And:
+
+::
+
+    [n_key n_value left right] key R0              [BTree-get] R1
+    [n_key n_value left right] key [dup first] dip [BTree-get] R1
+    [n_key n_value left right] n_key key           [BTree-get] R1
+    [n_key n_value left right] n_key key           [BTree-get] roll> [T>] [E] [T<] cmp
+    [n_key n_value left right] [BTree-get] n_key key                 [T>] [E] [T<] cmp
+
+    BTree-delete == [pop not] swap [[dup first] dip] [roll> [T>] [E] [T<] cmp] genrec
+
+::
+
+    [n_key n_value left right] [BTree-get] T>
+    [n_key n_value left right] [BTree-get] E
+    [n_key n_value left right] [BTree-get] T<
+
+::
+
+    [n_key n_value left right] [BTree-get] 
+    [n_key n_value left right] [BTree-get] E
+    [n_key n_value left right] [BTree-get] T<
+
+Tree with node and list of trees.
+=================================
+
+Let's consider a tree structure, similar to one described `"Why
+functional programming matters" by John
+Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__,
+that consists of a node value and a sequence of zero or more child
+trees. (The asterisk is meant to indicate the `Kleene
+star <https://en.wikipedia.org/wiki/Kleene_star>`__.)
+
+::
+
+    tree = [] | [node [tree*]]
+
+``treestep``
+~~~~~~~~~~~~
+
+In the spirit of ``step`` we are going to define a combinator
+``treestep`` which expects a tree and three additional items: a
+base-case value ``z``, and two quoted programs ``[C]`` and ``[N]``.
+
+::
+
+    tree z [C] [N] treestep
+
+If the current tree node is empty then just leave ``z`` on the stack in
+lieu:
+
+::
+
+       [] z [C] [N] treestep
+    ---------------------------
+          z
+
+Otherwise, evaluate ``N`` on the node value, ``map`` the whole function
+(abbreviated here as ``k``) over the child trees recursively, and then
+combine the result with ``C``.
+
+::
+
+       [node [tree*]] z [C] [N] treestep
+    --------------------------------------- w/ K == z [C] [N] treestep
+           node N [tree*] [K] map C
+
+Derive the recursive form.
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since this is a recursive function, we can begin to derive it by finding
+the ``ifte`` stage that ``genrec`` will produce. The predicate and
+base-case functions are trivial, so we just have to derive ``J``.
+
+::
+
+    K == [not] [pop z] [J] ifte
+
+The behavior of ``J`` is to accept a (non-empty) tree node and arrive at
+the desired outcome.
+
+::
+
+           [node [tree*]] J
+    ------------------------------
+       node N [tree*] [K] map C
+
+So ``J`` will have some form like:
+
+::
+
+    J == .. [N] .. [K] .. [C] ..
+
+Let's dive in. First, unquote the node and ``dip`` ``N``.
+
+::
+
+    [node [tree*]] i [N] dip
+     node [tree*]    [N] dip
+    node N [tree*]
+
+Next, ``map`` ``K`` over teh child trees and combine with ``C``.
+
+::
+
+    node N [tree*] [K] map C
+    node N [tree*] [K] map C
+    node N [K.tree*]       C
+
+So:
+
+::
+
+    J == i [N] dip [K] map C
+
+Plug it in and convert to ``genrec``:
+
+::
+
+    K == [not] [pop z] [i [N] dip [K] map C] ifte
+    K == [not] [pop z] [i [N] dip]   [map C] genrec
+
+Extract the givens to parameterize the program.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+    [not] [pop z] [i [N] dip]   [map C] genrec
+
+    [not] [pop z]                   [i [N] dip] [map C] genrec
+    [not] [z]         [pop] swoncat [i [N] dip] [map C] genrec
+    [not]  z     unit [pop] swoncat [i [N] dip] [map C] genrec
+    z [not] swap unit [pop] swoncat [i [N] dip] [map C] genrec
+      \  .........TS0............./
+       \/
+    z TS0 [i [N] dip]                       [map C] genrec
+    z     [i [N] dip]             [TS0] dip [map C] genrec
+    z       [[N] dip] [i] swoncat [TS0] dip [map C] genrec
+    z  [N] [dip] cons [i] swoncat [TS0] dip [map C] genrec
+           \  ......TS1........./
+            \/
+    z [N] TS1 [TS0] dip [map C]                      genrec
+    z [N]               [map C]  [TS1 [TS0] dip] dip genrec
+    z [N] [C]      [map] swoncat [TS1 [TS0] dip] dip genrec
+    z [C] [N] swap [map] swoncat [TS1 [TS0] dip] dip genrec
+
+The givens are all to the left so we have our definition.
+
+Define ``treestep``
+~~~~~~~~~~~~~~~~~~~
+
+::
+
+         TS0 == [not] swap unit [pop] swoncat
+         TS1 == [dip] cons [i] swoncat
+    treestep == swap [map] swoncat [TS1 [TS0] dip] dip genrec
+
+.. code:: ipython2
+
+    DefinitionWrapper.add_definitions('''
+    
+         TS0 == [not] swap unit [pop] swoncat
+         TS1 == [dip] cons [i] swoncat
+    treestep == swap [map] swoncat [TS1 [TS0] dip] dip genrec
+    
+    ''', D)
+
+::
+
+       [] 0 [C] [N] treestep
+    ---------------------------
+          0
+
+
+          [n [tree*]] 0 [sum +] [] treestep
+       --------------------------------------------------
+           n [tree*] [0 [sum +] [] treestep] map sum +
+
+.. code:: ipython2
+
+    J('[] 0 [sum +] [] treestep')
+
+
+.. parsed-literal::
+
+    0
+
+
+.. code:: ipython2
+
+    J('[23 []] 0 [sum +] [] treestep')
+
+
+.. parsed-literal::
+
+    23
+
+
+.. code:: ipython2
+
+    J('[23 [[2 []] [3 []]]] 0 [sum +] [] treestep')
+
+
+.. parsed-literal::
+
+    28
+
+
+A slight modification.
+----------------------
+
+Let's simplify the tree datastructure definition slightly by just
+letting the children be the ``rest`` of the tree:
+
+::
+
+    tree = [] | [node tree*]
+
+The ``J`` function changes slightly.
+
+::
+
+            [node tree*] J
+    ------------------------------
+       node N [tree*] [K] map C
+
+
+    [node tree*] uncons [N] dip [K] map C
+    node [tree*]        [N] dip [K] map C
+    node N [tree*]              [K] map C
+    node N [tree*]              [K] map C
+    node N [K.tree*]                    C
+
+    J == uncons [N] dip [K] map C
+
+    K == [not] [pop z] [uncons [N] dip] [map C] genrec
+
+.. code:: ipython2
+
+    define('TS1 == [dip] cons [uncons] swoncat')  # We only need to redefine one word.
+
+.. code:: ipython2
+
+    J('[23 [2] [3]] 0 [sum +] [] treestep')
+
+
+.. parsed-literal::
+
+    28
+
+
+.. code:: ipython2
+
+    J('[23 [2 [8] [9]] [3] [4 []]] 0 [sum +] [] treestep')
+
+
+.. parsed-literal::
+
+    49
+
+
+I think these trees seem a little easier to read.
+
+Redefining our BTree in terms of this form.
+-------------------------------------------
+
+::
+
+    BTree = [] | [[key value] left right]
+
+What kind of functions can we write for this with our ``treestep``? The
+pattern for processing a non-empty node is:
+
+::
+
+    node N [tree*] [K] map C
+
+Plugging in our BTree structure:
+
+::
+
+    [key value] N [left right] [K] map C
+
+
+    [key value] uncons pop [left right] [K] map i
+    key [value]        pop [left right] [K] map i
+    key                    [left right] [K] map i
+    key                    [lkey rkey ]         i
+    key                     lkey rkey
+
+.. code:: ipython2
+
+    J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]]   23 [i] [uncons pop] treestep')
+
+
+.. parsed-literal::
+
+    3 23 23
+
+
+Doesn't work because ``map`` extracts the ``first`` item of whatever its
+mapped function produces. We have to return a list, rather than
+depositing our results directly on the stack.
+
+::
+
+    [key value] N     [left right] [K] map C
+
+    [key value] first [left right] [K] map flatten cons
+    key               [left right] [K] map flatten cons
+    key               [[lk] [rk] ]         flatten cons
+    key               [ lk   rk  ]                 cons
+                      [key  lk   rk  ]
+
+So:
+
+::
+
+    [] [flatten cons] [first] treestep
+
+.. code:: ipython2
+
+    J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]]   [] [flatten cons] [first] treestep')
+
+
+.. parsed-literal::
+
+    [3 2 9 5 4 8 6 7]
+
+
+There we go. #### In-order traversal with ``treestep``.
+
+From here:
+
+::
+
+    key [[lk] [rk]] C
+    key [[lk] [rk]] i
+    key  [lk] [rk] roll<
+    [lk] [rk] key swons concat
+    [lk] [key rk]       concat
+    [lk   key rk]
+
+So:
+
+::
+
+    [] [i roll< swons concat] [first] treestep
+
+.. code:: ipython2
+
+    J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]]   [] [i roll< swons concat] [uncons pop] treestep')
+
+
+.. parsed-literal::
+
+    [2 3 4 5 6 7 8 9]
+
+
+Miscellaneous Crap
+------------------
+
+Toy with it.
+~~~~~~~~~~~~
+
+Let's reexamine:
+
+::
+
+    [key value left right] R0 [BTree-iter-order] R1
+        ...
+    left BTree-iter-order key value F right BTree-iter-order
+
+
+    [key value left right] disenstacken swap
+     key value left right               swap
+     key value right left
+
+    key value right left [BTree-iter-order] [cons dipdd] dupdip
+    key value right left [BTree-iter-order] cons dipdd [BTree-iter-order]
+    key value right [left BTree-iter-order]      dipdd [BTree-iter-order]
+    left BTree-iter-order key value right              [BTree-iter-order]
+
+    left BTree-iter-order key value   right [F] dip [BTree-iter-order]
+    left BTree-iter-order key value F right         [BTree-iter-order] i
+    left BTree-iter-order key value F right          BTree-iter-order
+
+So:
+
+::
+
+    R0 == disenstacken swap
+    R1 == [cons dipdd [F] dip] dupdip i
+
+    [key value left right] R0                [BTree-iter-order] R1
+    [key value left right] disenstacken swap [BTree-iter-order] [cons dipdd [F] dip] dupdip i
+     key value right left                    [BTree-iter-order] [cons dipdd [F] dip] dupdip i
+
+     key value right left [BTree-iter-order] cons dipdd [F] dip [BTree-iter-order] i
+     key value right [left BTree-iter-order]      dipdd [F] dip [BTree-iter-order] i
+     left BTree-iter-order key value   right            [F] dip [BTree-iter-order] i
+     left BTree-iter-order key value F right                    [BTree-iter-order] i
+     left BTree-iter-order key value F right                     BTree-iter-order
+
+
+    BTree-iter-order == [not] [pop] [disenstacken swap] [[cons dipdd [F] dip] dupdip i] genrec
+
+Refactor ``cons cons``
+^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+    cons2 == cons cons
+
+Refactoring:
+
+::
+
+    BTree-new == swap [[] []] cons2
+    T == [cons2 dipdd] cons2 cons infra
+    Te == [cons2 dipd] cons2 cons infra
+    Ee == pop swap roll< rest rest cons2
+
+It's used a lot because it's tied to the fact that there are two "data
+items" in each node. This point to a more general factorization that
+would render a combinator that could work for other geometries of trees.
+
+A General Form for Trees
+------------------------
+
+A general form for tree data with N children per node:
+
+::
+
+    [[data] [child0] ... [childN-1]]
+
+Suggests a general form of recursive iterator, but I have to go walk the
+dogs at the mo'.
+
+For a given structure, you would have a structure of operator functions
+and sort of merge them and run them, possibly in a different order (pre-
+post- in- y'know). The ``Cn`` functions could all be the same and use
+the ``step`` trick if the children nodes are all of the right kind. If
+they are heterogeneous then we need a way to get the different ``Cn``
+into the structure in the right order. If I understand correctly, the
+"Bananas..." paper shows how to do this automatically from a type
+description. They present, if I have it right, a tiny machine that
+accepts `some sort of algebraic data type description and returns a
+function that can recusre over
+it <https://en.wikipedia.org/wiki/Catamorphism#General_case>`__, I
+think.
+
+::
+
+       [data.. [c0] [c1] ... [cN]] [F C0 C1 ... CN] infil
+    --------------------------------------------------------
+       data F [c0] C0 [c1] C1 ... [cN] CN
+       
+       
+
+Just make ``[F]`` a parameter.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We can generalize to a sort of pure form:
+
+::
+
+    BTree-iter == [not] [pop] [[F]]            [R1] genrec
+               == [not] [pop] [[F] [BTree-iter] R1] ifte
+
+Putting ``[F]`` to the left as a given:
+
+::
+
+     [F] unit [not] [pop] roll< [R1] genrec
+    [[F]]     [not] [pop] roll< [R1] genrec
+              [not] [pop] [[F]] [R1] genrec
+
+Let's us define a parameterized form:
+
+::
+
+    BTree-iter == unit [not] [pop] roll< [R1] genrec
+
+So in the general case of non-empty nodes:
+
+::
+
+    [key value left right] [F] [BTree-iter] R1
+
+We just define ``R1`` to do whatever it has to to process the node. For
+example:
+
+::
+
+    [key value left right] [F] [BTree-iter] R1
+        ...
+    key value F   left BTree-iter   right BTree-iter
+    left BTree-iter   key value F   right BTree-iter
+    left BTree-iter   right BTree-iter   key value F
+
+Pre-, ??-, post-order traversals.
+
+::
+
+    [key value  left right] uncons uncons
+     key value [left right]
+
+For pre- and post-order we can use the ``step`` trick:
+
+::
+
+    [left right] [BTree-iter] step
+        ...
+    left BTree-iter right BTree-iter
+
+We worked out one scheme for ?in-order? traversal above, but maybe we
+can do better?
+
+::
+
+    [key value left right]              [F] [BTree-iter] [disenstacken] dipd
+    [key value left right] disenstacken [F] [BTree-iter]
+     key value left right               [F] [BTree-iter]
+
+    key value left right [F] [BTree-iter] R1.1
+
+Hmm...
+
+::
+
+    key value left right              [F] [BTree-iter] tuck
+    key value left right [BTree-iter] [F] [BTree-iter] 
+
+
+    [key value left right]                          [F] [BTree-iter] [disenstacken [roll>] dip] dipd
+    [key value left right] disenstacken [roll>] dip [F] [BTree-iter]
+     key value left right               [roll>] dip [F] [BTree-iter]
+     key value left roll> right                     [F] [BTree-iter]
+     left key value right                           [F] [BTree-iter]
+
+    left            key value   right              [F] [BTree-iter] tuck foo
+    left            key value   right [BTree-iter] [F] [BTree-iter] foo
+        ...
+    left BTree-iter key value F right  BTree-iter
+
+We could just let ``[R1]`` be a parameter too, for maximum flexibility.
+
+Automatically deriving the recursion combinator for a data type?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If I understand it correctly, the "Bananas..." paper talks about a way
+to build the processor function automatically from the description of
+the type. I think if we came up with an elegant way for the Joy code to
+express that, it would be cool. In Joypy the definitions can be circular
+because lookup happens at evaluation, not parsing. E.g.:
+
+::
+
+    A == ... B ...
+    B == ... A ...
+
+That's fine. Circular datastructures can't be made though.
diff --git a/docs/Zipper.rst b/docs/Zipper.rst
new file mode 100644 (file)
index 0000000..8bc5e5f
--- /dev/null
@@ -0,0 +1,353 @@
+
+This notebook is about using the "zipper" with joy datastructures. See
+the `Zipper wikipedia
+entry <https://en.wikipedia.org/wiki/Zipper_%28data_structure%29>`__ or
+the original paper: `"FUNCTIONAL PEARL The Zipper" by Gérard
+Huet <https://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf>`__
+
+Given a datastructure on the stack we can navigate through it, modify
+it, and rebuild it using the "zipper" technique.
+
+Preamble
+~~~~~~~~
+
+.. code:: ipython2
+
+    from notebook_preamble import J, V, define
+
+Trees
+-----
+
+In Joypy there aren't any complex datastructures, just ints, floats,
+strings, Symbols (strings that are names of functions) and sequences
+(aka lists, aka quoted literals, aka aggregates, etc...), but we can
+build
+`trees <https://en.wikipedia.org/wiki/Tree_%28data_structure%29>`__ out
+of sequences.
+
+.. code:: ipython2
+
+    J('[1 [2 [3 4 25 6] 7] 8]')
+
+
+.. parsed-literal::
+
+    [1 [2 [3 4 25 6] 7] 8]
+
+
+Zipper in Joy
+-------------
+
+Zippers work by keeping track of the current item, the already-seen
+items, and the yet-to-be seen items as you traverse a datastructure (the
+datastructure used to keep track of these items is the zipper.)
+
+In Joy we can do this with the following words:
+
+::
+
+    z-down == [] swap uncons swap
+    z-up == swons swap shunt
+    z-right == [swons] cons dip uncons swap
+    z-left == swons [uncons swap] dip swap
+
+Let's use them to change 25 into 625. The first time a word is used I
+show the trace so you can see how it works. If we were going to use
+these a lot it would make sense to write Python versions for efficiency,
+but see below.
+
+.. code:: ipython2
+
+    define('z-down == [] swap uncons swap')
+    define('z-up == swons swap shunt')
+    define('z-right == [swons] cons dip uncons swap')
+    define('z-left == swons [uncons swap] dip swap')
+
+.. code:: ipython2
+
+    V('[1 [2 [3 4 25 6] 7] 8] z-down')
+
+
+.. parsed-literal::
+
+                              . [1 [2 [3 4 25 6] 7] 8] z-down
+       [1 [2 [3 4 25 6] 7] 8] . z-down
+       [1 [2 [3 4 25 6] 7] 8] . [] swap uncons swap
+    [1 [2 [3 4 25 6] 7] 8] [] . swap uncons swap
+    [] [1 [2 [3 4 25 6] 7] 8] . uncons swap
+    [] 1 [[2 [3 4 25 6] 7] 8] . swap
+    [] [[2 [3 4 25 6] 7] 8] 1 . 
+
+
+.. code:: ipython2
+
+    V('[] [[2 [3 4 25 6] 7] 8] 1 z-right')
+
+
+.. parsed-literal::
+
+                                      . [] [[2 [3 4 25 6] 7] 8] 1 z-right
+                                   [] . [[2 [3 4 25 6] 7] 8] 1 z-right
+              [] [[2 [3 4 25 6] 7] 8] . 1 z-right
+            [] [[2 [3 4 25 6] 7] 8] 1 . z-right
+            [] [[2 [3 4 25 6] 7] 8] 1 . [swons] cons dip uncons swap
+    [] [[2 [3 4 25 6] 7] 8] 1 [swons] . cons dip uncons swap
+    [] [[2 [3 4 25 6] 7] 8] [1 swons] . dip uncons swap
+                                   [] . 1 swons [[2 [3 4 25 6] 7] 8] uncons swap
+                                 [] 1 . swons [[2 [3 4 25 6] 7] 8] uncons swap
+                                 [] 1 . swap cons [[2 [3 4 25 6] 7] 8] uncons swap
+                                 1 [] . cons [[2 [3 4 25 6] 7] 8] uncons swap
+                                  [1] . [[2 [3 4 25 6] 7] 8] uncons swap
+             [1] [[2 [3 4 25 6] 7] 8] . uncons swap
+             [1] [2 [3 4 25 6] 7] [8] . swap
+             [1] [8] [2 [3 4 25 6] 7] . 
+
+
+.. code:: ipython2
+
+    J('[1] [8] [2 [3 4 25 6] 7] z-down')
+
+
+.. parsed-literal::
+
+    [1] [8] [] [[3 4 25 6] 7] 2
+
+
+.. code:: ipython2
+
+    J('[1] [8] [] [[3 4 25 6] 7] 2 z-right')
+
+
+.. parsed-literal::
+
+    [1] [8] [2] [7] [3 4 25 6]
+
+
+.. code:: ipython2
+
+    J('[1] [8] [2] [7] [3 4 25 6] z-down')
+
+
+.. parsed-literal::
+
+    [1] [8] [2] [7] [] [4 25 6] 3
+
+
+.. code:: ipython2
+
+    J('[1] [8] [2] [7] [] [4 25 6] 3 z-right')
+
+
+.. parsed-literal::
+
+    [1] [8] [2] [7] [3] [25 6] 4
+
+
+.. code:: ipython2
+
+    J('[1] [8] [2] [7] [3] [25 6] 4 z-right')
+
+
+.. parsed-literal::
+
+    [1] [8] [2] [7] [4 3] [6] 25
+
+
+.. code:: ipython2
+
+    J('[1] [8] [2] [7] [4 3] [6] 25 sqr')
+
+
+.. parsed-literal::
+
+    [1] [8] [2] [7] [4 3] [6] 625
+
+
+.. code:: ipython2
+
+    V('[1] [8] [2] [7] [4 3] [6] 625 z-up')
+
+
+.. parsed-literal::
+
+                                  . [1] [8] [2] [7] [4 3] [6] 625 z-up
+                              [1] . [8] [2] [7] [4 3] [6] 625 z-up
+                          [1] [8] . [2] [7] [4 3] [6] 625 z-up
+                      [1] [8] [2] . [7] [4 3] [6] 625 z-up
+                  [1] [8] [2] [7] . [4 3] [6] 625 z-up
+            [1] [8] [2] [7] [4 3] . [6] 625 z-up
+        [1] [8] [2] [7] [4 3] [6] . 625 z-up
+    [1] [8] [2] [7] [4 3] [6] 625 . z-up
+    [1] [8] [2] [7] [4 3] [6] 625 . swons swap shunt
+    [1] [8] [2] [7] [4 3] [6] 625 . swap cons swap shunt
+    [1] [8] [2] [7] [4 3] 625 [6] . cons swap shunt
+    [1] [8] [2] [7] [4 3] [625 6] . swap shunt
+    [1] [8] [2] [7] [625 6] [4 3] . shunt
+      [1] [8] [2] [7] [3 4 625 6] . 
+
+
+.. code:: ipython2
+
+    J('[1] [8] [2] [7] [3 4 625 6] z-up')
+
+
+.. parsed-literal::
+
+    [1] [8] [2 [3 4 625 6] 7]
+
+
+.. code:: ipython2
+
+    J('[1] [8] [2 [3 4 625 6] 7] z-up')
+
+
+.. parsed-literal::
+
+    [1 [2 [3 4 625 6] 7] 8]
+
+
+``dip`` and ``infra``
+---------------------
+
+In Joy we have the ``dip`` and ``infra`` combinators which can "target"
+or "address" any particular item in a Joy tree structure.
+
+.. code:: ipython2
+
+    V('[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra')
+
+
+.. parsed-literal::
+
+                                                                    . [1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra
+                                             [1 [2 [3 4 25 6] 7] 8] . [[[[[[sqr] dipd] infra] dip] infra] dip] infra
+    [1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] . infra
+                                               8 [2 [3 4 25 6] 7] 1 . [[[[[sqr] dipd] infra] dip] infra] dip [] swaack
+            8 [2 [3 4 25 6] 7] 1 [[[[[sqr] dipd] infra] dip] infra] . dip [] swaack
+                                                 8 [2 [3 4 25 6] 7] . [[[[sqr] dipd] infra] dip] infra 1 [] swaack
+                      8 [2 [3 4 25 6] 7] [[[[sqr] dipd] infra] dip] . infra 1 [] swaack
+                                                     7 [3 4 25 6] 2 . [[[sqr] dipd] infra] dip [8] swaack 1 [] swaack
+                                7 [3 4 25 6] 2 [[[sqr] dipd] infra] . dip [8] swaack 1 [] swaack
+                                                       7 [3 4 25 6] . [[sqr] dipd] infra 2 [8] swaack 1 [] swaack
+                                          7 [3 4 25 6] [[sqr] dipd] . infra 2 [8] swaack 1 [] swaack
+                                                           6 25 4 3 . [sqr] dipd [7] swaack 2 [8] swaack 1 [] swaack
+                                                     6 25 4 3 [sqr] . dipd [7] swaack 2 [8] swaack 1 [] swaack
+                                                               6 25 . sqr 4 3 [7] swaack 2 [8] swaack 1 [] swaack
+                                                               6 25 . dup mul 4 3 [7] swaack 2 [8] swaack 1 [] swaack
+                                                            6 25 25 . mul 4 3 [7] swaack 2 [8] swaack 1 [] swaack
+                                                              6 625 . 4 3 [7] swaack 2 [8] swaack 1 [] swaack
+                                                            6 625 4 . 3 [7] swaack 2 [8] swaack 1 [] swaack
+                                                          6 625 4 3 . [7] swaack 2 [8] swaack 1 [] swaack
+                                                      6 625 4 3 [7] . swaack 2 [8] swaack 1 [] swaack
+                                                      7 [3 4 625 6] . 2 [8] swaack 1 [] swaack
+                                                    7 [3 4 625 6] 2 . [8] swaack 1 [] swaack
+                                                7 [3 4 625 6] 2 [8] . swaack 1 [] swaack
+                                                8 [2 [3 4 625 6] 7] . 1 [] swaack
+                                              8 [2 [3 4 625 6] 7] 1 . [] swaack
+                                           8 [2 [3 4 625 6] 7] 1 [] . swaack
+                                            [1 [2 [3 4 625 6] 7] 8] . 
+
+
+If you read the trace carefully you'll see that about half of it is the
+``dip`` and ``infra`` combinators de-quoting programs and "digging" into
+the subject datastructure. Instead of maintaining temporary results on
+the stack they are pushed into the pending expression (continuation).
+When ``sqr`` has run the rest of the pending expression rebuilds the
+datastructure.
+
+``Z``
+-----
+
+Imagine a function ``Z`` that accepts a sequence of ``dip`` and
+``infra`` combinators, a quoted program ``[Q]``, and a datastructure to
+work on. It would effectively execute the quoted program as if it had
+been embedded in a nested series of quoted programs, e.g.:
+
+::
+
+       [...] [Q] [dip dip infra dip infra dip infra] Z
+    -------------------------------------------------------------
+       [...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
+       
+
+The ``Z`` function isn't hard to make.
+
+.. code:: ipython2
+
+    define('Z == [[] cons cons] step i')
+
+Here it is in action in a simplified scenario.
+
+.. code:: ipython2
+
+    V('1 [2 3 4] Z')
+
+
+.. parsed-literal::
+
+                                 . 1 [2 3 4] Z
+                               1 . [2 3 4] Z
+                       1 [2 3 4] . Z
+                       1 [2 3 4] . [[] cons cons] step i
+        1 [2 3 4] [[] cons cons] . step i
+              1 2 [[] cons cons] . i [3 4] [[] cons cons] step i
+                             1 2 . [] cons cons [3 4] [[] cons cons] step i
+                          1 2 [] . cons cons [3 4] [[] cons cons] step i
+                           1 [2] . cons [3 4] [[] cons cons] step i
+                           [1 2] . [3 4] [[] cons cons] step i
+                     [1 2] [3 4] . [[] cons cons] step i
+      [1 2] [3 4] [[] cons cons] . step i
+          [1 2] 3 [[] cons cons] . i [4] [[] cons cons] step i
+                         [1 2] 3 . [] cons cons [4] [[] cons cons] step i
+                      [1 2] 3 [] . cons cons [4] [[] cons cons] step i
+                       [1 2] [3] . cons [4] [[] cons cons] step i
+                       [[1 2] 3] . [4] [[] cons cons] step i
+                   [[1 2] 3] [4] . [[] cons cons] step i
+    [[1 2] 3] [4] [[] cons cons] . step i
+      [[1 2] 3] 4 [[] cons cons] . i i
+                     [[1 2] 3] 4 . [] cons cons i
+                  [[1 2] 3] 4 [] . cons cons i
+                   [[1 2] 3] [4] . cons i
+                   [[[1 2] 3] 4] . i
+                                 . [[1 2] 3] 4
+                       [[1 2] 3] . 4
+                     [[1 2] 3] 4 . 
+
+
+And here it is doing the main thing.
+
+.. code:: ipython2
+
+    J('[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z')
+
+
+.. parsed-literal::
+
+    [1 [2 [3 4 625 6] 7] 8]
+
+
+Addressing
+----------
+
+Because we are only using two combinators we could replace the list with
+a string made from only two characters.
+
+::
+
+       [...] [Q] 'ddididi' Zstr
+    -------------------------------------------------------------
+       [...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
+
+The string can be considered a name or address for an item in the
+subject datastructure.
+
+Determining the right "path" for an item in a tree.
+---------------------------------------------------
+
+It's easy to read off (in reverse) the right sequence of "d" and "i"
+from the subject datastructure:
+
+::
+
+    [ n [ n [ n n x ...
+    i d i d i d d Bingo!
index f0e9a5f..1797697 100644 (file)
@@ -15,7 +15,7 @@
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
-#    along with Thun.  If not see <http://www.gnu.org/licenses/>.
+#    along with Thun.  If not see <http://www.gnu.org/licenses/>. 
 #
 '''
 This module contains the Joy function infrastructure and a library of
@@ -72,7 +72,7 @@ ALIASES = (
   )
 
 
-def add_aliases(D, A=ALIASES):
+def add_aliases(D, A):
   '''
   Given a dict and a iterable of (name, [alias, ...]) pairs, create
   additional entries in the dict mapping each alias to the named function
@@ -230,11 +230,18 @@ class DefinitionWrapper(object):
 
   @classmethod
   def add_definitions(class_, defs, dictionary):
+    '''
+    Scan multi-line string defs for definitions and add them to the
+    dictionary.
+    '''
     for definition in _text_to_defs(defs):
       class_.add_def(definition, dictionary)
 
   @classmethod
   def add_def(class_, definition, dictionary):
+    '''
+    Add the definition to the dictionary.
+    '''
     F = class_.parse_definition(definition)
     dictionary[F.name] = F
 
@@ -250,23 +257,36 @@ def _text_to_defs(text):
 
 @inscribe
 @SimpleFunctionWrapper
-def parse((text, stack)):
+def parse(stack):
   '''Parse the string on the stack to a Joy expression.'''
+  text, stack = stack
   expression = text_to_expression(text)
   return expression, stack
 
 
 @inscribe
 @SimpleFunctionWrapper
-def first(((head, tail), stack)):
-  '''first == uncons pop'''
+def first(stack):
+  '''
+  ::
+
+    first == uncons pop
+
+  '''
+  ((head, tail), stack) = stack
   return head, stack
 
 
 @inscribe
 @SimpleFunctionWrapper
-def rest(((head, tail), stack)):
-  '''rest == uncons popd'''
+def rest(stack):
+  '''
+  ::
+
+    rest == uncons popd
+
+  '''
+  ((head, tail), stack) = stack
   return tail, stack
 
 
@@ -274,14 +294,17 @@ def rest(((head, tail), stack)):
 @SimpleFunctionWrapper
 def getitem(stack):
   '''
-  getitem == drop first
+  ::
+
+    getitem == drop first
 
   Expects an integer and a quote on the stack and returns the item at the
   nth position in the quote counting from 0.
+  ::
 
-     [a b c d] 0 getitem
-  -------------------------
-              a
+       [a b c d] 0 getitem
+    -------------------------
+                a
 
   '''
   n, (Q, stack) = stack
@@ -292,14 +315,17 @@ def getitem(stack):
 @SimpleFunctionWrapper
 def drop(stack):
   '''
-  drop == [rest] times
+  ::
+
+    drop == [rest] times
 
   Expects an integer and a quote on the stack and returns the quote with
   n items removed off the top.
+  ::
 
-     [a b c d] 2 drop
-  ----------------------
-         [c d]
+       [a b c d] 2 drop
+    ----------------------
+           [c d]
 
   '''
   n, (Q, stack) = stack
@@ -319,10 +345,11 @@ def take(stack):
   Expects an integer and a quote on the stack and returns the quote with
   just the top n items in reverse order (because that's easier and you can
   use reverse if needed.)
+  ::
 
-     [a b c d] 2 take
-  ----------------------
-         [b a]
+       [a b c d] 2 take
+    ----------------------
+           [b a]
 
   '''
   n, (Q, stack) = stack
@@ -342,6 +369,7 @@ def take(stack):
 def choice(stack):
   '''
   Use a Boolean value to select one of two items.
+  ::
 
         A B False choice
      ----------------------
@@ -364,6 +392,7 @@ def choice(stack):
 def select(stack):
   '''
   Use a Boolean value to select one of two items from a sequence.
+  ::
 
         [A B] False select
      ------------------------
@@ -416,10 +445,11 @@ def remove(S):
   '''
   Expects an item on the stack and a quote under it and removes that item
   from the the quote.  The item is only removed once.
+  ::
 
-     [1 2 3 1] 1 remove
-  ------------------------
-          [2 3 1]
+       [1 2 3 1] 1 remove
+    ------------------------
+            [2 3 1]
 
   '''
   (tos, (second, stack)) = S
@@ -474,9 +504,10 @@ def uncons(S):
 @SimpleFunctionWrapper
 def clear(stack):
   '''Clear everything from the stack.
+  ::
 
-     ... clear
-  ---------------
+       ... clear
+    ---------------
 
   '''
   return ()
@@ -495,10 +526,11 @@ def dup(S):
 def over(S):
   '''
   Copy the second item down on the stack to the top of the stack.
+  ::
 
-     a b over
-  --------------
-      a b a
+       a b over
+    --------------
+        a b a
 
   '''
   second = S[1][0]
@@ -510,10 +542,11 @@ def over(S):
 def tuck(S):
   '''
   Copy the item at TOS under the second item of the stack.
+  ::
 
-     a b tuck
-  --------------
-      b a b
+       a b tuck
+    --------------
+        b a b
 
   '''
   (tos, (second, stack)) = S
@@ -598,8 +631,9 @@ def dupd(S):
 @SimpleFunctionWrapper
 def reverse(S):
   '''Reverse the list on the top of the stack.
+  ::
 
-  reverse == [] swap shunt
+    reverse == [] swap shunt
   '''
   (tos, stack) = S
   res = ()
@@ -620,12 +654,14 @@ def concat(S):
 
 @inscribe
 @SimpleFunctionWrapper
-def shunt((tos, (second, stack))):
-  '''
-  shunt == [swons] step
+def shunt(stack):
+  '''Like concat but reverses the top list into the second.
+  ::
+
+    shunt == [swons] step
 
-  Like concat but reverses the top list into the second.
   '''
+  (tos, (second, stack)) = stack
   while tos:
     term, tos = tos
     second = term, second
@@ -668,10 +704,11 @@ def pred(S):
 def pm(stack):
   '''
   Plus or minus
+  ::
 
-     a b pm
-  -------------
-     a+b a-b
+       a b pm
+    -------------
+       a+b a-b
 
   '''
   a, (b, stack) = stack
@@ -714,7 +751,14 @@ def sqrt(a):
 @inscribe
 @SimpleFunctionWrapper
 def rollup(S):
-  '''a b c -> b c a'''
+  '''
+  ::
+
+       a b c
+    -----------
+       b c a
+
+  '''
   (a, (b, (c, stack))) = S
   return b, (c, (a, stack))
 
@@ -722,7 +766,14 @@ def rollup(S):
 @inscribe
 @SimpleFunctionWrapper
 def rolldown(S):
-  '''a b c -> c a b'''
+  '''
+  ::
+
+       a b c
+    -----------
+       c a b
+
+  '''
   (a, (b, (c, stack))) = S
   return c, (a, (b, stack))
 
@@ -857,10 +908,11 @@ def i(stack, expression, dictionary):
   '''
   The i combinator expects a quoted program on the stack and unpacks it
   onto the pending expression for evaluation.
+  ::
 
-     [Q] i
-  -----------
-      Q
+       [Q] i
+    -----------
+        Q
 
   '''
   quote, stack = stack
@@ -871,11 +923,13 @@ def i(stack, expression, dictionary):
 @FunctionWrapper
 def x(stack, expression, dictionary):
   '''
-  x == dup i
+  ::
+
+    x == dup i
 
-  ... [Q] x = ... [Q] dup i
-  ... [Q] x = ... [Q] [Q] i
-  ... [Q] x = ... [Q]  Q
+    ... [Q] x = ... [Q] dup i
+    ... [Q] x = ... [Q] [Q] i
+    ... [Q] x = ... [Q]  Q
 
   '''
   quote, _ = stack
@@ -886,10 +940,12 @@ def x(stack, expression, dictionary):
 @FunctionWrapper
 def b(stack, expression, dictionary):
   '''
-  b == [i] dip i
+  ::
 
-  ... [P] [Q] b == ... [P] i [Q] i
-  ... [P] [Q] b == ... P Q
+    b == [i] dip i
+
+    ... [P] [Q] b == ... [P] i [Q] i
+    ... [P] [Q] b == ... P Q
 
   '''
   q, (p, (stack)) = stack
@@ -900,12 +956,14 @@ def b(stack, expression, dictionary):
 @FunctionWrapper
 def dupdip(stack, expression, dictionary):
   '''
-  [F] dupdip == dup [F] dip
+  ::
+
+    [F] dupdip == dup [F] dip
 
-  ... a [F] dupdip
-  ... a dup [F] dip
-  ... a a   [F] dip
-  ... a F a
+    ... a [F] dupdip
+    ... a dup [F] dip
+    ... a a   [F] dip
+    ... a F a
 
   '''
   F, stack = stack
@@ -919,10 +977,11 @@ def infra(stack, expression, dictionary):
   '''
   Accept a quoted program and a list on the stack and run the program
   with the list as its stack.
+  ::
 
-     ... [a b c] [Q] . infra
-  -----------------------------
-     c b a . Q [...] swaack
+       ... [a b c] [Q] . infra
+    -----------------------------
+       c b a . Q [...] swaack
 
   '''
   (quote, (aggregate, stack)) = stack
@@ -934,6 +993,7 @@ def infra(stack, expression, dictionary):
 def genrec(stack, expression, dictionary):
   '''
   General Recursion Combinator.
+  ::
 
                           [if] [then] [rec1] [rec2] genrec
     ---------------------------------------------------------------------
@@ -956,10 +1016,12 @@ def genrec(stack, expression, dictionary):
   a quotation of the whole function.
 
   For example, given a (general recursive) function 'F':
+  ::
 
       F == [I] [T] [R1] [R2] genrec
 
   If the [I] if-part fails you must derive R1 and R2 from:
+  ::
 
       ... R1 [F] R2
 
@@ -967,16 +1029,18 @@ def genrec(stack, expression, dictionary):
   have to do to apply the quoted [F] in the proper way.  In effect, the
   genrec combinator turns into an ifte combinator with a quoted copy of
   the original definition in the else-part:
+  ::
 
       F == [I] [T] [R1]   [R2] genrec
         == [I] [T] [R1 [F] R2] ifte
 
-  (Primitive recursive functions are those where R2 == i.
+  Primitive recursive functions are those where R2 == i.
+  ::
 
       P == [I] [T] [R] primrec
         == [I] [T] [R [P] i] ifte
         == [I] [T] [R P] ifte
-  )
+
   '''
   (rec2, (rec1, stack)) = stack
   (then, (if_, _)) = stack
@@ -1029,8 +1093,11 @@ def branch(stack, expression, dictionary):
   '''
   Use a Boolean value to select one of two quoted programs to run.
 
+  ::
+
       branch == roll< choice i
 
+  ::
 
         False [F] [T] branch
      --------------------------
@@ -1038,7 +1105,7 @@ def branch(stack, expression, dictionary):
 
         True [F] [T] branch
      -------------------------
-               T
+                  T
 
   '''
   (then, (else_, (flag, stack))) = stack
@@ -1050,6 +1117,7 @@ def branch(stack, expression, dictionary):
 def ifte(stack, expression, dictionary):
   '''
   If-Then-Else Combinator
+  ::
 
                   ... [if] [then] [else] ifte
        ---------------------------------------------------
@@ -1079,10 +1147,11 @@ def dip(stack, expression, dictionary):
   The dip combinator expects a quoted program on the stack and below it
   some item, it hoists the item into the expression and runs the program
   on the rest of the stack.
+  ::
 
-     ... x [Q] dip
-  -------------------
-       ... Q x
+       ... x [Q] dip
+    -------------------
+         ... Q x
 
   '''
   (quote, (x, stack)) = stack
@@ -1095,10 +1164,11 @@ def dip(stack, expression, dictionary):
 def dipd(S, expression, dictionary):
   '''
   Like dip but expects two items.
+  ::
 
-     ... y x [Q] dip
-  ---------------------
-       ... Q y x
+       ... y x [Q] dip
+    ---------------------
+         ... Q y x
 
   '''
   (quote, (x, (y, stack))) = S
@@ -1111,10 +1181,11 @@ def dipd(S, expression, dictionary):
 def dipdd(S, expression, dictionary):
   '''
   Like dip but expects three items.
+  ::
 
-     ... z y x [Q] dip
-  -----------------------
-       ... Q z y x
+       ... z y x [Q] dip
+    -----------------------
+         ... Q z y x
 
   '''
   (quote, (x, (y, (z, stack)))) = S
@@ -1129,6 +1200,7 @@ def app1(S, expression, dictionary):
   Given a quoted program on TOS and anything as the second stack item run
   the program and replace the two args with the first result of the
   program.
+  ::
 
               ... x [Q] . app1
      -----------------------------------
@@ -1144,6 +1216,7 @@ def app1(S, expression, dictionary):
 @FunctionWrapper
 def app2(S, expression, dictionary):
   '''Like app1 with two items.
+  ::
 
             ... y x [Q] . app2
      -----------------------------------
@@ -1163,6 +1236,7 @@ def app2(S, expression, dictionary):
 @FunctionWrapper
 def app3(S, expression, dictionary):
   '''Like app1 with three items.
+  ::
 
             ... z y x [Q] . app3
      -----------------------------------
@@ -1185,6 +1259,7 @@ def app3(S, expression, dictionary):
 def step(S, expression, dictionary):
   '''
   Run a quoted program on each item in a sequence.
+  ::
 
           ... [] [Q] . step
        -----------------------
@@ -1196,9 +1271,9 @@ def step(S, expression, dictionary):
                ... a . Q
 
 
-     ... [a b c] [Q] . step
-  ----------------------------------------
-               ... a . Q [b c] [Q] step
+       ... [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.
@@ -1219,20 +1294,21 @@ def step(S, expression, dictionary):
 def times(stack, expression, dictionary):
   '''
   times == [-- dip] cons [swap] infra [0 >] swap while pop
+  ::
 
-     ... n [Q] . times
-  ---------------------  w/ n <= 0
-           ... .
+       ... n [Q] . times
+    ---------------------  w/ n <= 0
+             ... .
 
 
-     ... 1 [Q] . times
-  ---------------------------------
-           ... . Q
+       ... 1 [Q] . times
+    ---------------------------------
+             ... . Q
 
 
-     ... n [Q] . times
-  ---------------------------------  w/ n > 1
-           ... . Q (n - 1) [Q] times
+       ... n [Q] . times
+    ---------------------------------  w/ n > 1
+             ... . Q (n - 1) [Q] times
 
   '''
   # times == [-- dip] cons [swap] infra [0 >] swap while pop
@@ -1267,14 +1343,15 @@ def times(stack, expression, dictionary):
 def loop(stack, expression, dictionary):
   '''
   Basic loop combinator.
+  ::
 
-     ... True [Q] loop
-  -----------------------
-       ... Q [Q] loop
+       ... True [Q] loop
+    -----------------------
+          ... Q [Q] loop
 
-     ... False [Q] loop
-  ------------------------
-            ...
+       ... False [Q] loop
+    ------------------------
+              ...
 
   '''
   quote, (flag, stack) = stack
@@ -1351,9 +1428,10 @@ for F in (
   UnaryBuiltinWrapper(sqrt),
   ):
   inscribe(F)
+del F  # Otherwise Sphinx autodoc will pick it up.
 
 
-add_aliases(_dictionary)
+add_aliases(_dictionary, ALIASES)
 
 
 DefinitionWrapper.add_definitions(definitions, _dictionary)
diff --git a/joy/pribrary.py b/joy/pribrary.py
deleted file mode 100644 (file)
index a38f3c3..0000000
+++ /dev/null
@@ -1,1437 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#    Copyright © 2014, 2015, 2017, 2018 Simon Forman
-#
-#    This file is part of Thun
-#
-#    Thun is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation, either version 3 of the License, or
-#    (at your option) any later version.
-#
-#    Thun is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with Thun.  If not see <http://www.gnu.org/licenses/>.
-#
-'''
-This module contains the Joy function infrastructure and a library of
-functions.  Its main export is a Python function initialize() that
-returns a dictionary of Joy functions suitable for use with the joy()
-function.
-'''
-from inspect import getdoc
-from functools import wraps
-import operator, math
-
-from .parser import text_to_expression, Symbol
-from .utils.stack import list_to_stack, iter_stack, pick, pushback
-from .utils.brutal_hackery import rename_code_object
-
-
-_dictionary = {}
-
-
-def inscribe(function):
-  '''A decorator to inscribe functions into the default dictionary.'''
-  _dictionary[function.name] = function
-  return function
-
-
-def initialize():
-  '''Return a dictionary of Joy functions for use with joy().'''
-  return _dictionary.copy()
-
-
-ALIASES = (
-  ('add', ['+']),
-  ('and', ['&']),
-  ('bool', ['truthy']),
-  ('mul', ['*']),
-  ('truediv', ['/']),
-  ('mod', ['%', 'rem', 'remainder', 'modulus']),
-  ('eq', ['=']),
-  ('ge', ['>=']),
-  ('getitem', ['pick', 'at']),
-  ('gt', ['>']),
-  ('le', ['<=']),
-  ('lshift', ['<<']),
-  ('lt', ['<']),
-  ('ne', ['<>', '!=']),
-  ('rshift', ['>>']),
-  ('sub', ['-']),
-  ('xor', ['^']),
-  ('succ', ['++']),
-  ('pred', ['--']),
-  ('rolldown', ['roll<']),
-  ('rollup', ['roll>']),
-  ('id', ['•']),
-  )
-
-
-def add_aliases(D, A):
-  '''
-  Given a dict and a iterable of (name, [alias, ...]) pairs, create
-  additional entries in the dict mapping each alias to the named function
-  if it's in the dict.  Aliases for functions not in the dict are ignored.
-  '''
-  for name, aliases in A:
-    try:
-      F = D[name]
-    except KeyError:
-      continue
-    for alias in aliases:
-      D[alias] = F
-
-
-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
-unquoted == [i] dip
-enstacken == stack [clear] dip
-disenstacken == ? [uncons ?] loop pop
-? == dup truthy
-dinfrirst == dip infra first
-nullary == [stack] dinfrirst
-unary == [stack [pop] dip] dinfrirst
-binary == [stack [popop] dip] dinfrirst
-ternary == [stack [popop pop] dip] dinfrirst
-pam == [i] map
-run == [] swap infra
-sqr == dup mul
-size == 0 swap [pop ++] step
-cleave == [i] app2 [popd] dip
-average == [sum 1.0 *] [size] cleave /
-gcd == 1 [tuck modulus dup 0 >] loop pop
-least_fraction == dup [gcd] infra [div] concat map
-*fraction == [uncons] dip uncons [swap] dip concat [*] infra [*] dip cons
-*fraction0 == concat [[swap] dip * [*] dip] infra
-down_to_zero == [0 >] [dup --] while
-range_to_zero == unit [down_to_zero] infra
-anamorphism == [pop []] swap [dip swons] genrec
-range == [0 <=] [1 - dup] anamorphism
-while == swap [nullary] cons dup dipd concat loop
-dudipd == dup dipd
-primrec == [i] genrec
-step_zero == 0 roll> step
-'''
-
-##Zipper
-##z-down == [] swap uncons swap
-##z-up == swons swap shunt
-##z-right == [swons] cons dip uncons swap
-##z-left == swons [uncons swap] dip swap
-
-##Quadratic Formula
-##divisor == popop 2 *
-##minusb == pop neg
-##radical == swap dup * rollup * 4 * - sqrt
-##root1 == + swap /
-##root2 == - swap /
-##q0 == [[divisor] [minusb] [radical]] pam
-##q1 == [[root1] [root2]] pam
-##quadratic == [q0] ternary i [q1] ternary
-
-# Project Euler
-##'''\
-##PE1.1 == + dup [+] dip
-##PE1.2 == dup [3 & PE1.1] dip 2 >>
-##PE1.3 == 14811 swap [PE1.2] times pop
-##PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop
-##'''
-#PE1.2 == [PE1.1] step
-#PE1 == 0 0 66 [[3 2 1 3 1 2 3] PE1.2] times [3 2 1 3] PE1.2 pop
-)
-
-
-def FunctionWrapper(f):
-  '''Set name attribute.'''
-  if not f.__doc__:
-    raise ValueError('Function %s must have doc string.' % f.__name__)
-  f.name = f.__name__.rstrip('_')  # Don't shadow builtins.
-  return f
-
-
-def SimpleFunctionWrapper(f):
-  '''
-  Wrap functions that take and return just a stack.
-  '''
-  @FunctionWrapper
-  @wraps(f)
-  @rename_code_object(f.__name__)
-  def inner(stack, expression, dictionary):
-    return f(stack), expression, dictionary
-  return inner
-
-
-def BinaryBuiltinWrapper(f):
-  '''
-  Wrap functions that take two arguments and return a single result.
-  '''
-  @FunctionWrapper
-  @wraps(f)
-  @rename_code_object(f.__name__)
-  def inner(stack, expression, dictionary):
-    (a, (b, stack)) = stack
-    result = f(b, a)
-    return (result, stack), expression, dictionary
-  return inner
-
-
-def UnaryBuiltinWrapper(f):
-  '''
-  Wrap functions that take one argument and return a single result.
-  '''
-  @FunctionWrapper
-  @wraps(f)
-  @rename_code_object(f.__name__)
-  def inner(stack, expression, dictionary):
-    (a, stack) = stack
-    result = f(a)
-    return (result, stack), expression, dictionary
-  return inner
-
-
-class DefinitionWrapper(object):
-  '''
-  Provide implementation of defined functions, and some helper methods.
-  '''
-
-  def __init__(self, name, body_text, doc=None):
-    self.name = self.__name__ = name
-    self.body = text_to_expression(body_text)
-    self._body = tuple(iter_stack(self.body))
-    self.__doc__ = doc or body_text
-
-  def __call__(self, stack, expression, dictionary):
-    expression = list_to_stack(self._body, expression)
-    return stack, expression, dictionary
-
-  @classmethod
-  def parse_definition(class_, defi):
-    '''
-    Given some text describing a Joy function definition parse it and
-    return a DefinitionWrapper.
-    '''
-    name, proper, body_text = (n.strip() for n in defi.partition('=='))
-    if not proper:
-      raise ValueError('Definition %r failed' % (defi,))
-    return class_(name, body_text)
-
-  @classmethod
-  def add_definitions(class_, defs, dictionary):
-    '''
-    Scan multi-line string defs for definitions and add them to the
-    dictionary.
-    '''
-    for definition in _text_to_defs(defs):
-      class_.add_def(definition, dictionary)
-
-  @classmethod
-  def add_def(class_, definition, dictionary):
-    '''
-    Add the definition to the dictionary.
-    '''
-    F = class_.parse_definition(definition)
-    dictionary[F.name] = F
-
-
-def _text_to_defs(text):
-  return (line.strip() for line in text.splitlines() if '==' in line)
-
-
-#
-# Functions
-#
-
-
-@inscribe
-@SimpleFunctionWrapper
-def parse(stack):
-  '''Parse the string on the stack to a Joy expression.'''
-  text, stack = stack
-  expression = text_to_expression(text)
-  return expression, 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 getitem(stack):
-  '''
-  ::
-
-    getitem == drop first
-
-  Expects an integer and a quote on the stack and returns the item at the
-  nth position in the quote counting from 0.
-  ::
-
-       [a b c d] 0 getitem
-    -------------------------
-                a
-
-  '''
-  n, (Q, stack) = stack
-  return pick(Q, n), stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def drop(stack):
-  '''
-  ::
-
-    drop == [rest] times
-
-  Expects an integer and a quote on the stack and returns the quote with
-  n items removed off the top.
-  ::
-
-       [a b c d] 2 drop
-    ----------------------
-           [c d]
-
-  '''
-  n, (Q, stack) = stack
-  while n > 0:
-    try:
-      _, Q = Q
-    except ValueError:
-      raise IndexError
-    n -= 1
-  return Q, stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def take(stack):
-  '''
-  Expects an integer and a quote on the stack and returns the quote with
-  just the top n items in reverse order (because that's easier and you can
-  use reverse if needed.)
-  ::
-
-       [a b c d] 2 take
-    ----------------------
-           [b a]
-
-  '''
-  n, (Q, stack) = stack
-  x = ()
-  while n > 0:
-    try:
-      item, Q = Q
-    except ValueError:
-      raise IndexError
-    x = item, x
-    n -= 1
-  return x, stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def choice(stack):
-  '''
-  Use a Boolean value to select one of two items.
-  ::
-
-        A B False choice
-     ----------------------
-               A
-
-
-        A B True choice
-     ---------------------
-               B
-
-  Currently Python semantics are used to evaluate the "truthiness" of the
-  Boolean value (so empty string, zero, etc. are counted as false, etc.)
-  '''
-  (if_, (then, (else_, stack))) = stack
-  return then if if_ else else_, stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def select(stack):
-  '''
-  Use a Boolean value to select one of two items from a sequence.
-  ::
-
-        [A B] False select
-     ------------------------
-                A
-
-
-        [A B] True select
-     -----------------------
-               B
-
-  The sequence can contain more than two items but not fewer.
-  Currently Python semantics are used to evaluate the "truthiness" of the
-  Boolean value (so empty string, zero, etc. are counted as false, etc.)
-  '''
-  (flag, (choices, stack)) = stack
-  (else_, (then, _)) = choices
-  return then if flag else else_, stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def max_(S):
-  '''Given a list find the maximum.'''
-  tos, stack = S
-  return max(iter_stack(tos)), stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def min_(S):
-  '''Given a list find the minimum.'''
-  tos, stack = S
-  return min(iter_stack(tos)), stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def sum_(S):
-  '''Given a quoted sequence of numbers return the sum.
-
-  sum == 0 swap [+] step
-  '''
-  tos, stack = S
-  return sum(iter_stack(tos)), stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def remove(S):
-  '''
-  Expects an item on the stack and a quote under it and removes that item
-  from the the quote.  The item is only removed once.
-  ::
-
-       [1 2 3 1] 1 remove
-    ------------------------
-            [2 3 1]
-
-  '''
-  (tos, (second, stack)) = S
-  l = list(iter_stack(second))
-  l.remove(tos)
-  return list_to_stack(l), stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def unique(S):
-  '''Given a list remove duplicate items.'''
-  tos, stack = S
-  I = list(iter_stack(tos))
-  list_to_stack(sorted(set(I), key=I.index))
-  return list_to_stack(sorted(set(I), key=I.index)), stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def sort_(S):
-  '''Given a list return it sorted.'''
-  tos, stack = 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 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 clear(stack):
-  '''Clear everything from the stack.
-  ::
-
-       ... clear
-    ---------------
-
-  '''
-  return ()
-
-
-@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 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 swaack(stack):
-  '''swap stack'''
-  old_stack, stack = 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 unstack(stack):
-  '''
-  The unstack operator expects a list on top of the stack and makes that
-  the stack discarding the rest of the stack.
-  '''
-  return stack[0]
-
-
-@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 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 dupd(S):
-  '''Duplicate the second item on the stack.'''
-  (tos, (second, stack)) = S
-  return tos, (second, (second, stack))
-
-
-@inscribe
-@SimpleFunctionWrapper
-def reverse(S):
-  '''Reverse the list on the top of the stack.
-  ::
-
-    reverse == [] swap shunt
-  '''
-  (tos, stack) = S
-  res = ()
-  for term in iter_stack(tos):
-    res = term, res
-  return res, stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def concat(S):
-  '''Concatinate the two lists on the top of the stack.'''
-  (tos, (second, stack)) = S
-  for term in reversed(list(iter_stack(second))):
-    tos = term, tos
-  return tos, stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def shunt(xxx_todo_changeme3):
-  '''Like concat but reverses the top list into the second.
-  ::
-
-    shunt == [swons] step
-
-  '''
-  (tos, (second, stack)) = xxx_todo_changeme3
-  while tos:
-    term, tos = tos
-    second = term, second
-  return second, stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def zip_(S):
-  '''
-  Replace the two lists on the top of the stack with a list of the pairs
-  from each list.  The smallest list sets the length of the result list.
-  '''
-  (tos, (second, stack)) = S
-  accumulator = [
-    (a, (b, ()))
-    for a, b in zip(iter_stack(tos), iter_stack(second))
-    ]
-  return list_to_stack(accumulator), stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def succ(S):
-  '''Increment TOS.'''
-  (tos, stack) = S
-  return tos + 1, stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def pred(S):
-  '''Decrement TOS.'''
-  (tos, stack) = S
-  return tos - 1, stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def pm(stack):
-  '''
-  Plus or minus
-  ::
-
-       a b pm
-    -------------
-       a+b a-b
-
-  '''
-  a, (b, stack) = stack
-  p, m, = b + a, b - a
-  return m, (p, stack)
-
-
-def floor(n):
-  return int(math.floor(n))
-
-floor.__doc__ = math.floor.__doc__
-
-
-@inscribe
-@SimpleFunctionWrapper
-def divmod_(S):
-  '''
-  divmod(x, y) -> (quotient, remainder)
-
-  Return the tuple (x//y, x%y).  Invariant: div*y + mod == x.
-  '''
-  a, (b, stack) = S
-  d, m = divmod(a, b)
-  return d, (m, stack)
-
-
-def sqrt(a):
-  '''
-  Return the square root of the number a.
-  Negative numbers return complex roots.
-  '''
-  try:
-    r = math.sqrt(a)
-  except ValueError:
-    assert a < 0, repr(a)
-    r = math.sqrt(-a) * 1j
-  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 rolldown(S):
-  '''
-  ::
-
-       a b c
-    -----------
-       c a b
-
-  '''
-  (a, (b, (c, stack))) = S
-  return c, (a, (b, stack))
-
-
-#def execute(S):
-#  (text, stack) = S
-#  if isinstance(text, str):
-#    return run(text, stack)
-#  return stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def id_(stack):
-  '''The identity function.'''
-  return stack
-
-
-@inscribe
-@SimpleFunctionWrapper
-def void(stack):
-  '''True if the form on TOS is void otherwise False.'''
-  form, stack = stack
-  return _void(form), stack
-
-
-def _void(form):
-  return any(not _void(i) for i in iter_stack(form))
-
-
-
-##  transpose
-##  sign
-##  take
-
-
-@inscribe
-@FunctionWrapper
-def words(stack, expression, dictionary):
-  '''Print all the words in alphabetical order.'''
-  print((' '.join(sorted(dictionary))))
-  return stack, expression, dictionary
-
-
-@inscribe
-@FunctionWrapper
-def sharing(stack, expression, dictionary):
-  '''Print redistribution information.'''
-  print("You may convey verbatim copies of the Program's source code as"
-        ' you receive it, in any medium, provided that you conspicuously'
-        ' and appropriately publish on each copy an appropriate copyright'
-        ' notice; keep intact all notices stating that this License and'
-        ' any non-permissive terms added in accord with section 7 apply'
-        ' to the code; keep intact all notices of the absence of any'
-        ' warranty; and give all recipients a copy of this License along'
-        ' with the Program.'
-        ' You should have received a copy of the GNU General Public License'
-        ' along with Thun.  If not see <http://www.gnu.org/licenses/>.')
-  return stack, expression, dictionary
-
-
-@inscribe
-@FunctionWrapper
-def warranty(stack, expression, dictionary):
-  '''Print warranty information.'''
-  print('THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY'
-        ' APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE'
-        ' COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM'
-        ' "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR'
-        ' IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES'
-        ' OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE'
-        ' ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS'
-        ' WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE'
-        ' COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.')
-  return stack, expression, dictionary
-
-
-# def simple_manual(stack):
-#   '''
-#   Print words and help for each word.
-#   '''
-#   for name, f in sorted(FUNCTIONS.items()):
-#     d = getdoc(f)
-#     boxline = '+%s+' % ('-' * (len(name) + 2))
-#     print('\n'.join((
-#       boxline,
-#       '| %s |' % (name,),
-#       boxline,
-#       d if d else '   ...',
-#       '',
-#       '--' * 40,
-#       '',
-#       )))
-#   return stack
-
-
-@inscribe
-@FunctionWrapper
-def help_(S, expression, dictionary):
-  '''Accepts a quoted symbol on the top of the stack and prints its docs.'''
-  ((symbol, _), stack) = S
-  word = dictionary[symbol]
-  print((getdoc(word)))
-  return stack, expression, dictionary
-
-
-#
-# § Combinators
-#
-
-
-# Several combinators depend on other words in their definitions,
-# we use symbols to prevent hard-coding these, so in theory, you
-# could change the word in the dictionary to use different semantics.
-S_choice = Symbol('choice')
-S_first = Symbol('first')
-S_getitem = Symbol('getitem')
-S_genrec = Symbol('genrec')
-S_loop = Symbol('loop')
-S_i = Symbol('i')
-S_ifte = Symbol('ifte')
-S_infra = Symbol('infra')
-S_step = Symbol('step')
-S_times = Symbol('times')
-S_swaack = Symbol('swaack')
-S_truthy = Symbol('truthy')
-
-
-@inscribe
-@FunctionWrapper
-def i(stack, expression, dictionary):
-  '''
-  The i combinator expects a quoted program on the stack and unpacks it
-  onto the pending expression for evaluation.
-  ::
-
-       [Q] i
-    -----------
-        Q
-
-  '''
-  quote, stack = stack
-  return stack, pushback(quote, expression), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def x(stack, expression, dictionary):
-  '''
-  ::
-
-    x == dup i
-
-    ... [Q] x = ... [Q] dup i
-    ... [Q] x = ... [Q] [Q] i
-    ... [Q] x = ... [Q]  Q
-
-  '''
-  quote, _ = stack
-  return stack, pushback(quote, expression), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def b(stack, expression, dictionary):
-  '''
-  ::
-
-    b == [i] dip i
-
-    ... [P] [Q] b == ... [P] i [Q] i
-    ... [P] [Q] b == ... P Q
-
-  '''
-  q, (p, (stack)) = stack
-  return stack, pushback(p, pushback(q, expression)), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def dupdip(stack, expression, dictionary):
-  '''
-  ::
-
-    [F] dupdip == dup [F] dip
-
-    ... a [F] dupdip
-    ... a dup [F] dip
-    ... a a   [F] dip
-    ... a F a
-
-  '''
-  F, stack = stack
-  a = stack[0]
-  return stack, pushback(F, (a,  expression)), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def infra(stack, expression, dictionary):
-  '''
-  Accept a quoted program and a list on the stack and run the program
-  with the list as its stack.
-  ::
-
-       ... [a b c] [Q] . infra
-    -----------------------------
-       c b a . Q [...] swaack
-
-  '''
-  (quote, (aggregate, stack)) = stack
-  return aggregate, pushback(quote, (stack, (S_swaack, expression))), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def genrec(stack, expression, dictionary):
-  '''
-  General Recursion Combinator.
-  ::
-
-                          [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."
-
-  The way to design one of these is to fix your base case [then] and the
-  test [if], and then treat rec1 and rec2 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
-
-  If the [I] if-part fails you must derive R1 and R2 from:
-  ::
-
-      ... R1 [F] R2
-
-  Just 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.  In effect, the
-  genrec combinator turns into an ifte combinator with a quoted copy of
-  the original definition in the else-part:
-  ::
-
-      F == [I] [T] [R1]   [R2] genrec
-        == [I] [T] [R1 [F] R2] ifte
-
-  Primitive recursive functions are those where R2 == i.
-  ::
-
-      P == [I] [T] [R] primrec
-        == [I] [T] [R [P] i] ifte
-        == [I] [T] [R P] ifte
-
-  '''
-  (rec2, (rec1, stack)) = stack
-  (then, (if_, _)) = stack
-  F = (if_, (then, (rec1, (rec2, (S_genrec, ())))))
-  else_ = pushback(rec1, (F, rec2))
-  return (else_, stack), (S_ifte, expression), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def map_(S, expression, dictionary):
-  '''
-  Run the quoted program on TOS on the items in the list under it, push a
-  new list with the results (in place of the program and original list.
-  '''
-#  (quote, (aggregate, stack)) = S
-#  results = list_to_stack([
-#    joy((term, stack), quote, dictionary)[0][0]
-#    for term in iter_stack(aggregate)
-#    ])
-#  return (results, stack), expression, dictionary
-  (quote, (aggregate, stack)) = S
-  if not aggregate:
-    return (aggregate, stack), expression, dictionary
-  batch = ()
-  for term in iter_stack(aggregate):
-    s = term, stack
-    batch = (s, (quote, (S_infra, (S_first, batch))))
-  stack = (batch, ((), stack))
-  return stack, (S_infra, expression), dictionary
-
-
-#def cleave(S, expression, dictionary):
-#  '''
-#  The cleave combinator expects two quotations, and below that an item X.
-#  It first executes [P], with X on top, and saves the top result element.
-#  Then it executes [Q], again with X, and saves the top result.
-#  Finally it restores the stack to what it was below X and pushes the two
-#  results P(X) and Q(X).
-#  '''
-#  (Q, (P, (x, stack))) = S
-#  p = joy((x, stack), P, dictionary)[0][0]
-#  q = joy((x, stack), Q, dictionary)[0][0]
-#  return (q, (p, stack)), expression, dictionary
-
-
-@inscribe
-@FunctionWrapper
-def branch(stack, expression, dictionary):
-  '''
-  Use a Boolean value to select one of two quoted programs to run.
-
-  ::
-
-      branch == roll< choice i
-
-  ::
-
-        False [F] [T] branch
-     --------------------------
-               F
-
-        True [F] [T] branch
-     -------------------------
-                  T
-
-  '''
-  (then, (else_, (flag, stack))) = stack
-  return stack, pushback(then if flag else else_, expression), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def ifte(stack, expression, dictionary):
-  '''
-  If-Then-Else Combinator
-  ::
-
-                  ... [if] [then] [else] ifte
-       ---------------------------------------------------
-          ... [[else] [then]] [...] [if] infra select i
-
-
-
-
-                ... [if] [then] [else] ifte
-       -------------------------------------------------------
-          ... [else] [then] [...] [if] infra first choice i
-
-
-  Has the effect of grabbing a copy of the stack on which to run the
-  if-part using infra.
-  '''
-  (else_, (then, (if_, stack))) = stack
-  expression = (S_infra, (S_first, (S_choice, (S_i, expression))))
-  stack = (if_, (stack, (then, (else_, stack))))
-  return stack, expression, dictionary
-
-
-@inscribe
-@FunctionWrapper
-def dip(stack, expression, dictionary):
-  '''
-  The dip combinator expects a quoted program on the stack and below it
-  some item, it hoists the item into the expression and runs the program
-  on the rest of the stack.
-  ::
-
-       ... x [Q] dip
-    -------------------
-         ... Q x
-
-  '''
-  (quote, (x, stack)) = stack
-  expression = (x, expression)
-  return stack, pushback(quote, expression), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def dipd(S, expression, dictionary):
-  '''
-  Like dip but expects two items.
-  ::
-
-       ... y x [Q] dip
-    ---------------------
-         ... Q y x
-
-  '''
-  (quote, (x, (y, stack))) = S
-  expression = (y, (x, expression))
-  return stack, pushback(quote, expression), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def dipdd(S, expression, dictionary):
-  '''
-  Like dip but expects three items.
-  ::
-
-       ... z y x [Q] dip
-    -----------------------
-         ... Q z y x
-
-  '''
-  (quote, (x, (y, (z, stack)))) = S
-  expression = (z, (y, (x, expression)))
-  return stack, pushback(quote, expression), dictionary
-
-
-@inscribe
-@FunctionWrapper
-def app1(S, expression, dictionary):
-  '''
-  Given a quoted program on TOS and anything as the second stack item run
-  the program and replace the two args with the first result of the
-  program.
-  ::
-
-              ... x [Q] . app1
-     -----------------------------------
-        ... [x ...] [Q] . infra first
-  '''
-  (quote, (x, stack)) = S
-  stack = (quote, ((x, stack), stack))
-  expression = (S_infra, (S_first, expression))
-  return stack, expression, dictionary
-
-
-@inscribe
-@FunctionWrapper
-def app2(S, expression, dictionary):
-  '''Like app1 with two items.
-  ::
-
-            ... y x [Q] . app2
-     -----------------------------------
-        ... [y ...] [Q] . infra first
-            [x ...] [Q]   infra first
-
-  '''
-  (quote, (x, (y, stack))) = S
-  expression = (S_infra, (S_first,
-    ((x, stack), (quote, (S_infra, (S_first,
-      expression))))))
-  stack = (quote, ((y, stack), stack))
-  return stack, expression, dictionary
-
-
-@inscribe
-@FunctionWrapper
-def app3(S, expression, dictionary):
-  '''Like app1 with three items.
-  ::
-
-            ... z y x [Q] . app3
-     -----------------------------------
-        ... [z ...] [Q] . infra first
-            [y ...] [Q]   infra first
-            [x ...] [Q]   infra first
-
-  '''
-  (quote, (x, (y, (z, stack)))) = S
-  expression = (S_infra, (S_first,
-    ((y, stack), (quote, (S_infra, (S_first,
-    ((x, stack), (quote, (S_infra, (S_first,
-      expression))))))))))
-  stack = (quote, ((z, stack), stack))
-  return stack, expression, dictionary
-
-
-@inscribe
-@FunctionWrapper
-def step(S, expression, dictionary):
-  '''
-  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.
-  '''
-  (quote, (aggregate, stack)) = S
-  if not aggregate:
-    return stack, expression, dictionary
-  head, tail = aggregate
-  stack = quote, (head, stack)
-  if tail:
-    expression = tail, (quote, (S_step, expression))
-  expression = S_i, expression
-  return stack, expression, dictionary
-
-
-@inscribe
-@FunctionWrapper
-def times(stack, expression, dictionary):
-  '''
-  times == [-- dip] cons [swap] infra [0 >] swap while pop
-  ::
-
-       ... n [Q] . times
-    ---------------------  w/ n <= 0
-             ... .
-
-
-       ... 1 [Q] . times
-    ---------------------------------
-             ... . Q
-
-
-       ... n [Q] . times
-    ---------------------------------  w/ n > 1
-             ... . Q (n - 1) [Q] times
-
-  '''
-  # times == [-- dip] cons [swap] infra [0 >] swap while pop
-  (quote, (n, stack)) = stack
-  if n <= 0:
-    return stack, expression, dictionary
-  n -= 1
-  if n:
-    expression = n, (quote, (S_times, expression))
-  expression = pushback(quote, expression)
-  return stack, expression, dictionary
-
-
-# The current definition above works like this:
-
-#             [P] [Q] while
-# --------------------------------------
-#    [P] nullary [Q [P] nullary] loop
-
-#   while == [pop i not] [popop] [dudipd] primrec
-
-#def while_(S, expression, dictionary):
-#  '''[if] [body] while'''
-#  (body, (if_, stack)) = S
-#  while joy(stack, if_, dictionary)[0][0]:
-#    stack = joy(stack, body, dictionary)[0]
-#  return stack, expression, dictionary
-
-
-@inscribe
-@FunctionWrapper
-def loop(stack, expression, dictionary):
-  '''
-  Basic loop combinator.
-  ::
-
-       ... True [Q] loop
-    -----------------------
-          ... Q [Q] loop
-
-       ... False [Q] loop
-    ------------------------
-              ...
-
-  '''
-  quote, (flag, stack) = stack
-  if flag:
-    expression = pushback(quote, (quote, (S_loop, expression)))
-  return stack, expression, dictionary
-
-
-#def nullary(S, expression, dictionary):
-#  '''
-#  Run the program on TOS and return its first result without consuming
-#  any of the stack (except the program on TOS.)
-#  '''
-#  (quote, stack) = S
-#  result = joy(stack, quote, dictionary)
-#  return (result[0][0], stack), expression, dictionary
-#
-#
-#def unary(S, expression, dictionary):
-#  (quote, stack) = S
-#  _, return_stack = stack
-#  result = joy(stack, quote, dictionary)[0]
-#  return (result[0], return_stack), expression, dictionary
-#
-#
-#def binary(S, expression, dictionary):
-#  (quote, stack) = S
-#  _, (_, return_stack) = stack
-#  result = joy(stack, quote, dictionary)[0]
-#  return (result[0], return_stack), expression, dictionary
-#
-#
-#def ternary(S, expression, dictionary):
-#  (quote, stack) = S
-#  _, (_, (_, return_stack)) = stack
-#  result = joy(stack, quote, dictionary)[0]
-#  return (result[0], return_stack), expression, dictionary
-
-
-#  FunctionWrapper(binary),
-#  FunctionWrapper(cleave),
-#  FunctionWrapper(nullary),
-#  FunctionWrapper(ternary),
-#  FunctionWrapper(unary),
-#  FunctionWrapper(while_),
-
-
-for F in (
-  BinaryBuiltinWrapper(operator.add),
-  BinaryBuiltinWrapper(operator.and_),
-  BinaryBuiltinWrapper(operator.div),
-  BinaryBuiltinWrapper(operator.eq),
-  BinaryBuiltinWrapper(operator.floordiv),
-  BinaryBuiltinWrapper(operator.ge),
-  BinaryBuiltinWrapper(operator.gt),
-  BinaryBuiltinWrapper(operator.le),
-  BinaryBuiltinWrapper(operator.lshift),
-  BinaryBuiltinWrapper(operator.lt),
-  BinaryBuiltinWrapper(operator.mod),
-  BinaryBuiltinWrapper(operator.mul),
-  BinaryBuiltinWrapper(operator.ne),
-  BinaryBuiltinWrapper(operator.or_),
-  BinaryBuiltinWrapper(operator.pow),
-  BinaryBuiltinWrapper(operator.rshift),
-  BinaryBuiltinWrapper(operator.sub),
-  BinaryBuiltinWrapper(operator.truediv),
-  BinaryBuiltinWrapper(operator.xor),
-
-  UnaryBuiltinWrapper(abs),
-  UnaryBuiltinWrapper(bool),
-  UnaryBuiltinWrapper(floor),
-  UnaryBuiltinWrapper(operator.neg),
-  UnaryBuiltinWrapper(operator.not_),
-  UnaryBuiltinWrapper(sqrt),
-  ):
-  inscribe(F)
-del F  # Otherwise Sphinx autodoc will pick it up.
-
-
-add_aliases(_dictionary, ALIASES)
-
-
-DefinitionWrapper.add_definitions(definitions, _dictionary)