::
- $ 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.
+ $ 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
+ <-top
- joy? _
+ 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
::
- joy? 23 sqr 18 +
- . 23 sqr 18 +
- 23 . sqr 18 +
- 23 . dup mul 18 +
- 23 23 . mul 18 +
- 529 . 18 +
- 529 18 . +
- 547 .
+ 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
+ 547 <-top
- joy?
+ joy?
Stacks (aka list, quote, sequence, etc.)
========================================
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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>`__*.
+all Joy datastructures are `purely
+functional <https://en.wikipedia.org/wiki/Purely_functional_data_structure>`__.
The ``joy()`` function.
=======================
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
+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.)
View function
~~~~~~~~~~~~~
-The ``joy()`` function accepts a "viewer" function which it calls on
+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
``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.
+left from the pending expression (“continuation”) on the right.
`Continuation-Passing Style <https://en.wikipedia.org/wiki/Continuation-passing_style>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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
+structure out of the tokens. There’s no Abstract Syntax Tree or anything
like that.
.. code:: ipython2
-That's pretty much all there is to it.
+That’s pretty much all there is to it.
.. code:: ipython2
Library
=======
-The Joy library of functions (aka commands, or "words" after Forth
+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
-Currently, there's no function to add new definitions to the dictionary
-from "within" Joy code itself. Adding new definitions remains a
+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
+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."
+“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
+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
+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.
+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"
+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
+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
``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
+left from the pending expression (“continuation”) on the right. I find
these traces beautiful, like a kind of art.
.. code:: ipython2
15 .
-Here's a longer trace.
+Here’s a longer trace.
.. code:: ipython2
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,
+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.)
+it’s “off the shelf” technology.)
``clear``
~~~~~~~~~
``roll<`` ``rolldown`` ``roll>`` ``rollup``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The "down" and "up" refer to the movement of two of the top three items
+The “down” and “up” refer to the movement of two of the top three items
(displacing the third.)
.. code:: ipython2
``swaack``
~~~~~~~~~~
-"Swap stack" swap the list on the top of the stack for the stack, and
+“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.
~~~~~~~~~~~~~~~~~~
If we represent fractions as a quoted pair of integers [q d] this word
-reduces them to their ... least common factors or whatever.
+reduces them to their … least common factors or whatever.
.. code:: ipython2
::
- ? == dup truthy
+ ? == dup truthy
.. code:: ipython2
::
- n [P] [G] anamorphism
- ---------------------------
- [...]
+ n [P] [G] anamorphism
+ ---------------------------
+ [...]
Example, ``range``:
::
- range == [0 <=] [1 - dup] anamorphism
+ range == [0 <=] [1 - dup] anamorphism
.. code:: ipython2
::
- ... x [P] [Q] cleave
+ ... x [P] [Q] cleave
-From the original Joy docs: "The cleave combinator expects two
+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)."
+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``
+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
+ cleave == [i] app2 [popd] dip
.. code:: ipython2
::
- n [Q] dupdip == n Q n
+ n [Q] dupdip == n Q n
.. code:: ipython2
::
- [predicate] [then] [else] ifte
+ [predicate] [then] [else] ifte
.. code:: ipython2
::
- [predicate] [body] while
+ [predicate] [body] while
.. code:: ipython2
``void``
========
-Implements `**Laws of Form**
-*arithmetic* <https://en.wikipedia.org/wiki/Laws_of_Form#The_primary_arithmetic_.28Chapter_4.29>`__
+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.)
-`Project Euler, first problem: "Multiples of 3 and 5" <https://projecteuler.net/problem=1>`__
+`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.
+ 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.
+ 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
+Let’s create a predicate that returns ``True`` if a number is a multiple
of 3 or 5 and ``False`` otherwise.
.. code:: ipython2
::
- PE1 == 1000 range [P] filter sum
+ 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.
::
- 3 5 6 9 10 12 15 18 20 21 ...
+ 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 ...
+ 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
+ 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.
::
- PE1.1 == + [+] dupdip
+ PE1.1 == + [+] dupdip
.. code:: ipython2
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
+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
::
- 3 2 1 3 1 2 3
- 0b 11 10 01 11 01 10 11 == 14811
+ 3 2 1 3 1 2 3
+ 0b 11 10 01 11 01 10 11 == 14811
.. code:: ipython2
233168
-Let's refactor.
+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
+ 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
233168
-Here's our joy program all in one place. It doesn't make so much sense,
+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.
+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
+ 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
+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.
466
-Here they are...
-~~~~~~~~~~~~~~~~
+Here they are…
+~~~~~~~~~~~~~~
.. code:: ipython2
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.
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+…and they do sum to 999.
+~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: ipython2
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,
+``pop`` the generator and the counter from the stack when we’re done,
leaving just the sum.
.. code:: ipython2
::
- 10 9 8 7 6
- + 1 2 3 4 5
- ---- -- -- -- --
- 11 11 11 11 11
-
- 11 * 5 = 55
+ 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
+ (N + 1) * N / 2
-(The formula also works for odd values of N, I'll leave that to you if
+(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
We can apply the same reasoning to the PE1 problem.
-Between 0 and 990 inclusive there are sixty-six "blocks" of seven terms
+Between 0 and 990 inclusive there are sixty-six “blocks” of seven terms
each, starting with:
::
- [3 5 6 9 10 12 15]
+ [3 5 6 9 10 12 15]
And ending with:
::
- [978 980 981 984 985 987 990]
+ [978 980 981 984 985 987 990]
-If we reverse one of these two blocks and sum pairs...
+If we reverse one of these two blocks and sum pairs…
.. code:: ipython2
::
- 993 995 996 999
+ 993 995 996 999
-So we can give the "sum of all the multiples of 3 or 5 below 1000" like
+So we can give the “sum of all the multiples of 3 or 5 below 1000” like
so:
.. code:: ipython2
233168
-It's worth noting, I think, that this same reasoning holds for any two
+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.
::
- | | | | | | | |
- | | | | |
+ | | | | | | | |
+ | | | | |
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
+*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.
::
- PE1 == 233168
+ PE1 == 233168
Fin.
from notebook_preamble import J, V, define
-I'll assume the input is a Joy sequence of integers (as opposed to a
+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
::
- AoC2017.1 == pair_up total_matches
+ AoC2017.1 == pair_up total_matches
-Let's derive ``pair_up``:
+Let’s derive ``pair_up``:
::
- [a b c] pair_up
- -------------------------
- [[a b] [b c] [c a]]
+ [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):
+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]]
+ [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
::
- total_matches == 0 swap [F] step
+ 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
+ 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′
+ total [n m] i F′
+ ----------------------
+ total n m F′
Now ``F′`` becomes just:
::
- total n m [=] [pop +] [popop] ifte
+ total n m [=] [pop +] [popop] ifte
So:
::
- F == i [=] [pop +] [popop] ifte
+ F == i [=] [pop +] [popop] ifte
And thus:
::
- total_matches == 0 swap [i [=] [pop +] [popop] ifte] step
+ total_matches == 0 swap [i [=] [pop +] [popop] ifte] step
.. code:: ipython2
::
- pair_up == dup uncons swap unit concat zip
- total_matches == 0 swap [i [=] [pop +] [popop] ifte] step
+ pair_up == dup uncons swap unit concat zip
+ total_matches == 0 swap [i [=] [pop +] [popop] ifte] step
- AoC2017.1 == pair_up total_matches
+ AoC2017.1 == pair_up total_matches
-Now the paired digit is "halfway" round.
+Now the paired digit is “halfway” round.
::
- [a b c d] dup size 2 / [drop] [take reverse] cleave concat zip
+ [a b c d] dup size 2 / [drop] [take reverse] cleave concat zip
.. code:: ipython2
[[3 1] [4 2] [1 3] [2 4]]
-I realized that each pair is repeated...
+I realized that each pair is repeated…
.. code:: ipython2
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...
+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
+ 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
+ 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
+ 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 *
+ AoC2017.1.extra == pair_up.extra total_matches 2 *
::
- 5 1 9 5
- 7 5 3
- 2 4 6 8
+ 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
+- 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
+- The second row’s largest and smallest values are 7 and 3, and their
difference is 4.
-- The third row's difference is 6.
+- The third row’s difference is 6.
-In this example, the spreadsheet's checksum would be 8 + 4 + 6 = 18.
+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.
+I’ll assume the input is a Joy sequence of sequences of integers.
::
- [[5 1 9 5]
- [7 5 3]
- [2 4 6 8]]
+ [[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
+ 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
::
- F == maxmin -
+ F == maxmin -
So:
18
-...find the only two numbers in each row where one evenly divides the
+…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.
+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
+ 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 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?
+What is the sum of each row’s result in your puzzle input?
.. code:: ipython2
::
- [9 8 5 2] uncons [swap [divmod] cons F] dupdip G
- [8 5 2] [9 divmod] F [8 5 2] G
+ [9 8 5 2] uncons [swap [divmod] cons F] dupdip G
+ [8 5 2] [9 divmod] F [8 5 2] G
.. code:: ipython2
Tricky
------
-Let's think.
+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
::
- [a b c d] True [Q] loop
- [a b c d] Q [Q] loop
+ [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
+ -----------------
+ result 0
- [a b c d] Q
- -----------------
- [b c d] 1
+ [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
+ [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.
+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
+ [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
+ 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
+ [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 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
+ [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
+ Q == [% not] [/ roll> popop 0] [pop swap uncons roll>] primrec
- uncons tuck uncons roll> Q
+ uncons tuck uncons roll> Q
.. code:: ipython2
::
- [a b c d] uncons
- a [b c d] tuck
- [b c d] a [b c d] [not] [popop 1] [Q] ifte
+ [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 [] popop 1
+ [b c d] 1
- [b c d] a [b c d] Q
+ [b c d] a [b c d] Q
- a [...] Q
- ---------------
- result 0
+ a [...] Q
+ ---------------
+ result 0
- a [...] Q
- ---------------
- 1
+ a [...] Q
+ ---------------
+ 1
- w/ Q == [first % not] [first / 0] [rest [not] [popop 1]] [ifte]
+ 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 % 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] 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 [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 [c d] [not] [popop 1] [Q] ifte
+ a [c d] not
- a [] popop 1
- 1
+ a [] popop 1
+ 1
- a [c d] Q
+ a [c d] Q
- uncons tuck [first % not] [first / 0] [rest [not] [popop 1]] [ifte]
+ uncons tuck [first % not] [first / 0] [rest [not] [popop 1]] [ifte]
I finally sat down with a piece of paper and blocked it out.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- n [...] G
- ---------------
- result
+ n [...] G
+ ---------------
+ result
- n [...] G
- ---------------
- 0
+ n [...] G
+ ---------------
+ 0
-It's a recursive function that conditionally executes the recursive part
+It’s a recursive function that conditionally executes the recursive part
of its recursive branch
::
- [Pg] [E] [R1 [Pi] [T]] [ifte] genrec
+ [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
+ 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
+ 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.
::
- n [m ...] rest [not] [popop 0] [G] ifte
- n [...] [not] [popop 0] [G] ifte
+ 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``.
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
+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
+ 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
::
- find-result == [0 >] [roll> popop] [roll< popop uncons [G] nullary] primrec
+ find-result == [0 >] [roll> popop] [roll< popop uncons [G] nullary] primrec
- n [...] p [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...
+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
+ 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
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.
+candidate value and zero (“continue”) flag.
.. code:: ipython2
::
- 17 16 15 14 13
- 18 5 4 3 12
- 19 6 1 2 11
- 20 7 8 9 10
- 21 22 23---> ...
+ 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
For example:
-- Data from square 1 is carried 0 steps, since it's at the access port.
+- 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.
~~~~~~~~
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.
+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
::
- 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
+ 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
+ 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.
+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
+ 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"
+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`
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
+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`:
+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
+ 0 1 2 3 4 5 6 7
+ 7 6 5 4 5 6 7 8
.. code:: ipython2
3 2 1 0 1 2 3 4
-Great, now add :math:`k`...
+Great, now add :math:`k`\ …
.. code:: ipython2
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
+(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.)
: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
+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
Find the rank for large numbers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Using e.g. Sympy we can find the rank directly by solving for the roots
+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.
-We can write a function to solve for :math:`k` given some :math:`n`...
+We can write a function to solve for :math:`k` given some :math:`n`\ …
.. code:: ipython2
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
+rank boundaries. I don’t know why. I’m basically like a monkey doing
math here.) =-D
It gives correct answers:
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
+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...
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+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)
g, f = solve(E - y, k)
The equation is quadratic so there are two roots, we are interested in
-the greater one...
+the greater one…
.. code:: ipython2
50 4
-It's pretty fast.
+It’s pretty fast.
.. code:: ipython2
(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
+: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)`.)
::
- n rank_of
- ---------------
- k
+ n rank_of
+ ---------------
+ k
The translation is straightforward.
::
- int(floor(sqrt(n - 1) / 2 - 0.5) + 1)
+ int(floor(sqrt(n - 1) / 2 - 0.5) + 1)
- rank_of == -- sqrt 2 / 0.5 - floor ++
+ rank_of == -- sqrt 2 / 0.5 - floor ++
.. code:: ipython2
::
- n k offset_of
- -------------------
- i
+ n k offset_of
+ -------------------
+ i
- (n - 2 + 4 * k * (k - 1)) % (2 * k)
+ (n - 2 + 4 * k * (k - 1)) % (2 * k)
-A little tricky...
+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 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 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
+ 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 %
+ offset_of == dup 2 * [dup -- 4 * * 2 + -] dip %
.. code:: ipython2
::
- k i row_value
- -------------------
- n
+ k i row_value
+ -------------------
+ n
- abs(i - (k - 1)) + k
+ 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|
+ 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
::
- n aoc2017.3
- -----------------
- m
+ 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
+ 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
::
- rank_of == -- sqrt 2 / 0.5 - floor ++
- offset_of == dup 2 * [dup -- 4 * * 2 + -] dip %
- row_value == over -- - abs +
+ 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
+ aoc2017.3 == dup rank_of [offset_of] dupdip swap row_value
- 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
+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.
+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]]
+ [[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
+ AoC2017.4 == 0 swap [F +] step
::
- F == [size] [unique size] cleave =
+ F == [size] [unique size] cleave =
The ``step_zero`` combinator includes the ``0 swap`` that would normally
open one of these definitions:
::
- AoC2017.4 == [F +] step_zero
+ AoC2017.4 == [F +] step_zero
.. code:: ipython2
December 5th
------------
-...a list of the offsets for each jump. Jumps are relative: -1 moves to
+…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.
::
- 0
- 3
- 0
- 1
- -3
+ 0
+ 3
+ 0
+ 1
+ -3
-Positive jumps ("forward") move downward; negative jumps move upward.
+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:
-
- (1) 3 0 1 -3 - jump with offset 0 (that is, don't jump at all).
+ (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.
+- ::
+
+ 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.
Breakdown
---------
-For now, I'm going to assume a starting state with the size of the
+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
::
- size index step-count [...] F
- -----------------------------------
- step-count
+ size index step-count [...] F
+ -----------------------------------
+ step-count
- F == [P] [T] [R1] [R2] genrec
+ 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!
+realized that the size properly belongs in the predicate of ``F``! D’oh!
::
- index step-count [...] F
- ------------------------------
- step-count
+ index step-count [...] F
+ ------------------------------
+ step-count
-So, let's start by nailing down the predicate:
+So, let’s start by nailing down the predicate:
::
- F == [P] [T] [R1] [R2] genrec
- == [P] [T] [R1 [F] R2] ifte
+ F == [P] [T] [R1] [R2] genrec
+ == [P] [T] [R1 [F] R2] ifte
- 0 0 [0 3 0 1 -3] popop 5 >=
+ 0 0 [0 3 0 1 -3] popop 5 >=
- P == popop 5 >=
+ P == popop 5 >=
Now we need the else-part:
::
- index step-count [0 3 0 1 -3] roll< popop
+ index step-count [0 3 0 1 -3] roll< popop
- E == roll< popop
+ E == roll< popop
Last but not least, the recursive branch
::
- 0 0 [0 3 0 1 -3] R1 [F] R2
+ 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
+ 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
+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".)
+function to use an array “under the hood”.)
-In the meantime, I'm going to write a primitive function that just does
+In the meantime, I’m going to write a primitive function that just does
what we need.
.. code:: ipython2
::
- 3 0 [0 1 2 3 4] [roll< at] nullary
- 3 0 [0 1 2 n 4] n
+ 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
+ 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]
+ 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]
+ 3+n 0 [0 1 2 n+1 4] [++] dip
+ 3+n 1 [0 1 2 n+1 4]
-All together now...
-~~~~~~~~~~~~~~~~~~~
+All together now…
+~~~~~~~~~~~~~~~~~
::
- get_value == [roll< at] nullary
- incr_value == [[popd incr_at] unary] dip
- add_value == [+] cons dipd
- incr_step_count == [++] dip
+ 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
+ R1 == get_value incr_value add_value incr_step_count
- F == [P] [T] [R1] primrec
+ F == [P] [T] [R1] primrec
- F == [popop !size! >=] [roll< pop] [get_value incr_value add_value incr_step_count] primrec
+ F == [popop !size! >=] [roll< pop] [get_value incr_value add_value incr_step_count] primrec
.. code:: ipython2
::
- [...] AoC2017.5.preamble
- ------------------------------
- 0 0 [...] [popop n >=]
+ [...] AoC2017.5.preamble
+ ------------------------------
+ 0 0 [...] [popop n >=]
Where ``n`` is the size of the sequence.
::
- [...] 0 0 roll< dup size
- 0 0 [...] n
+ [...] 0 0 roll< dup size
+ 0 0 [...] n
Then:
::
- 0 0 [...] n [>=] cons [popop] swoncat
+ 0 0 [...] n [>=] cons [popop] swoncat
So:
::
- init-index-and-step-count == 0 0 roll<
- prepare-predicate == dup size [>=] cons [popop] swoncat
+ 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.preamble == init-index-and-step-count prepare-predicate
.. code:: ipython2
::
- AoC2017.5 == AoC2017.5.preamble [roll< popop] [AoC2017.5.0] primrec
+ 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
+ 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
+ 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
+ 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
+still wouldn’t be as efficient as something written in assembly, C, or
even Python.
::
- [0 2 7 0] dup max
+ [0 2 7 0] dup max
.. code:: ipython2
-1
-Starting at ``index`` distribute ``count`` "blocks" to the "banks" in
+Starting at ``index`` distribute ``count`` “blocks” to the “banks” in
the sequence.
::
- [...] count index distribute
- ----------------------------
- [...]
+ [...] count index distribute
+ ----------------------------
+ [...]
-This seems like it would be a PITA to implement in Joypy...
+This seems like it would be a PITA to implement in Joypy…
.. code:: ipython2
[2 4 1 2]
-Recalling "Generator Programs"
+Recalling “Generator Programs”
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- [a F] x
- [a F] a F
+ [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
+ [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
+ w/ C == dup G
- a dup G [F] cons
- a a G [F] cons
+ a dup G [F] cons
+ a a G [F] cons
- w/ G == dup max [index_of] nullary distribute
+ w/ G == dup max [index_of] nullary distribute
.. code:: ipython2
::
- [] [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] 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
+ [] [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 --
+ [] [...] [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
+ [] [...] [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] [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
+ [[...]] [...] [GEN] F
What have we learned?
::
- F == [pop index_of 0 >=] [popop size] [[swons] dip x] primrec
+ F == [pop index_of 0 >=] [popop size] [[swons] dip x] primrec
.. code:: ipython2
::
- sqr == dup mul
+ sqr == dup mul
.. code:: ipython2
529 .
-It's simple to write a function to emit this kind of crude "compiled"
+It’s simple to write a function to emit this kind of crude “compiled”
code.
.. code:: ipython2
::
- quoted == [unit] dip
+ quoted == [unit] dip
.. code:: ipython2
Call-chaining results in code that does too much work. For functions
that operate on stacks and only rearrange values, what I like to call
-"Yin Functions", we can do better.
+“Yin Functions”, we can do better.
-We can infer the stack effects of these functions (or "expressions" or
-"programs") automatically, and the stack effects completely define the
+We can infer the stack effects of these functions (or “expressions” or
+“programs”) automatically, and the stack effects completely define the
semantics of the functions, so we can directly write out a two-line
Python function for them. This is already implemented in the
``joy.utils.types.compile_()`` function.
source = compile_('foo', stack_effects[0])
All Yin functions can be described in Python as a tuple-unpacking (or
-"-destructuring") of the stack datastructure followed by building up the
+“-destructuring”) of the stack datastructure followed by building up the
new stack structure.
.. code:: ipython2
Compiling from Stack Effects
----------------------------
-There are times when you're deriving a Joy program when you have a stack
+There are times when you’re deriving a Joy program when you have a stack
effect for a Yin function and you need to define it. For example, in the
Ordered Binary Trees notebook there is a point where we must derive a
function ``Ee``:
::
- [key old_value left right] new_value key [Tree-add] Ee
- ------------------------------------------------------------
- [key new_value left right]
+ [key old_value left right] new_value key [Tree-add] Ee
+ ------------------------------------------------------------
+ [key new_value left right]
While it is not hard to come up with this function manually, there is no
necessity. This function can be defined (in Python) directly from its
::
- [a b c d] e a [f] Ee
- --------------------------
- [a e c d]
+ [a b c d] e a [f] Ee
+ --------------------------
+ [a e c d]
-(I haven't yet implemented a simple interface for this yet. What follow
+(I haven’t yet implemented a simple interface for this yet. What follow
is an exploration of how to do it.)
.. code:: ipython2
stack_effect = eval('(((a1, (a2, s1)), (a5, (a6, (a7, s0)))), ((a1, (a5, s1)), s0))', tv)
The ``right`` and ``left`` parts of the ordered binary tree node are
-subsumed in the tail of the node's stack/list.
+subsumed in the tail of the node’s stack/list.
.. code:: ipython2
return ((a1, (a5, s1)), s0)
-Oops! The input stack is backwards...
+Oops! The input stack is backwards…
.. code:: ipython2
::
- [key old_value left right] new_value key [Tree-add] Ee
- ------------------------------------------------------------
- [key new_value left right]
+ [key old_value left right] new_value key [Tree-add] Ee
+ ------------------------------------------------------------
+ [key new_value left right]
.. code:: ipython2
-How about...
+How about…
.. code:: ipython2
Compiling Yin~Yang Functions
----------------------------
-First, we need a source of Python identifiers. I'm going to reuse
+First, we need a source of Python identifiers. I’m going to reuse
``Symbol`` class for this.
.. code:: ipython2
names = _names().next
Now we need an object that represents a Yang function that accepts two
-args and return one result (we'll implement other kinds a little later.)
+args and return one result (we’ll implement other kinds a little later.)
.. code:: ipython2
code.append(('call', out, self.name, (in0, in1)))
return (out, stack), expression, code
-A crude "interpreter" that translates expressions of args and Yin and
+A crude “interpreter” that translates expressions of args and Yin and
Yang functions into a kind of simple dataflow graph.
.. code:: ipython2
''' % (name, code_gen(I((), expression, [])))
-A few functions to try it with...
+A few functions to try it with…
.. code:: ipython2
def import_yin():
-... and there we are.
+… and there we are.
.. code:: ipython2
Introduction
============
-In 1969 George Spencer-Brown (GSB) published `"Laws of
-Form" <https://en.wikipedia.org/wiki/Laws_of_Form>`__ which presented a
+In 1969 George Spencer-Brown (GSB) published `“Laws of
+Form” <https://en.wikipedia.org/wiki/Laws_of_Form>`__ which presented a
logical system based on a single action, a distinction, that is both an
operation and a value. This notebook describes a Python implementation
that mimics the Laws of Form notation and uses it to develop a model of
::
- (()) =
- ()() = ()
+ (()) =
+ ()() = ()
Calculus
^^^^^^^^
::
- A((B)) = AB
- A() = ()
- A(AB) = A(B)
+ A((B)) = AB
+ A() = ()
+ A(AB) = A(B)
I call these three laws the **Bricken Basis** after `William
Bricken <http://wbricken.com/>`__ who figured out that the third law is
-complete with the other two. GSB had the first two laws and "Each Way"
+complete with the other two. GSB had the first two laws and “Each Way”
as the basis. (TODO: Find and include the references for all this.)
(If anything here is unclear read `The Markable
------------------------------------------------------------
We can use data structures made solely out of Python ``frozenset`` and
-string objects to represent the forms of the Laws of Form notation. I'm
-going to use the terms "expression" and "form" interchangably in this
+string objects to represent the forms of the Laws of Form notation. I’m
+going to use the terms “expression” and “form” interchangably in this
document.
.. code:: ipython2
-It's prefectly okay to create forms out of other forms (not just
+It’s prefectly okay to create forms out of other forms (not just
strings.)
.. code:: ipython2
return any(not void(i) for i in form)
The ``void()`` function returns a Boolean value (Python ``True`` or
-``False``), for convenience let's write a function that returns the Mark
+``False``), for convenience let’s write a function that returns the Mark
or Void value of a form.
.. code:: ipython2
-This is a bit hard to read, so let's define a helper function to convert
+This is a bit hard to read, so let’s define a helper function to convert
an environment to a string format.
.. code:: ipython2
Reify the Forms with Each Meaning
---------------------------------
-Let's pick one of the expressions and iterate through the environments
+Let’s pick one of the expressions and iterate through the environments
showing the result of reifying that expression in that environment.
.. code:: ipython2
Truth Table
-----------
-Let's render the above as a `Truth
+Let’s render the above as a `Truth
Table <https://en.wikipedia.org/wiki/Truth_table>`__.
.. code:: ipython2
This makes it clear that *each expression in Laws of Form calculus is
describing a digital Boolean circuit*. The names are its inputs and its
-Void/Mark value is its output. Each boundary is a `multi-input **NOR**
+Void/Mark value is its output. Each boundary is a `multi-input NOR
gate <https://en.wikipedia.org/wiki/Logical_NOR>`__, known as the Peirce
arrow or Quine dagger (See `Sheffer
stroke <https://en.wikipedia.org/wiki/Sheffer_stroke>`__ and `NOR
gate <https://en.wikipedia.org/wiki/NOR_gate>`__.) Instead of two
Boolean values there is only one value and non-existance.
-Let's build Circuits
+Let’s build Circuits
====================
-In order to work with expressions as digital circuits, let's define some
+In order to work with expressions as digital circuits, let’s define some
helper functions that will create logic circuits out of simpler forms.
The names of the functions below reflect the choice of Mark as Boolean
``True`` but this is `just a convention <#Appendix:-Duals>`__.
((((((((b) c) ((c) b)))) a) (((((b) c) ((c) b))) (a))))
-And let's rewrite the ``truth_table_3()`` function to make it work for
+And let’s rewrite the ``truth_table_3()`` function to make it work for
any number of variables.
.. code:: ipython2
`brute-force <https://en.wikipedia.org/wiki/Brute-force_search>`__
`SAT <https://en.wikipedia.org/wiki/Boolean_satisfiability_problem>`__
`solver <https://en.wikipedia.org/wiki/Boolean_satisfiability_problem#Algorithms_for_solving_SAT>`__
-that doesn't even bother to stop once it's found a solution.
+that doesn’t even bother to stop once it’s found a solution.
Expressions from Truth Tables
-----------------------------
Sometimes we will have a function for which we know the behavior (truth
table) but not an expression and we want the expression. For example,
-imagine that we didn't just create the expression for this table:
+imagine that we didn’t just create the expression for this table:
::
- a b c | Value
- ---------+------
- |
- () |
- () |
- () () | ()
- () |
- () () | ()
- () () | ()
- () () () |
+ a b c | Value
+ ---------+------
+ |
+ () |
+ () |
+ () () | ()
+ () |
+ () () | ()
+ () () | ()
+ () () () |
Each Row can be Represented as an Expression
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- ⟶ ( a b c )
- () ⟶ ( a b (c))
- () ⟶ ( a (b) c )
- () () ⟶ ( a (b) (c))
- () ⟶ ((a) b c )
- () () ⟶ ((a) b (c))
- () () ⟶ ((a) (b) c )
- () () () ⟶ ((a) (b) (c))
+ ⟶ ( a b c )
+ () ⟶ ( a b (c))
+ () ⟶ ( a (b) c )
+ () () ⟶ ( a (b) (c))
+ () ⟶ ((a) b c )
+ () () ⟶ ((a) b (c))
+ () () ⟶ ((a) (b) c )
+ () () () ⟶ ((a) (b) (c))
Each of the above expressions will be true (Mark-valued) for only one
-possible combination of the three input variables. For example, let's
+possible combination of the three input variables. For example, let’s
look at the sixth expression above:
.. code:: ipython2
To make an expression that is Mark-valued for just certain rows of the
-table, pick those rows' expressions,
+table, pick those rows’ expressions,
::
- () () | ( a (b) (c))
- () () | ((a) b (c))
- () () | ((a) (b) c )
+ () () | ( a (b) (c))
+ () () | ((a) b (c))
+ () () | ((a) (b) c )
And write them down as terms in an **OR** expression:
::
- E = (a(b)(c)) ((a)b(c)) ((a)(b)c)
+ E = (a(b)(c)) ((a)b(c)) ((a)(b)c)
In conventional notation this is called `Disjunctive normal
form <https://en.wikipedia.org/wiki/Disjunctive_normal_form>`__:
::
- E = (¬a ∧ b ∧ c) ∨ (a ∧ ¬b ∧ c) ∨ (a ∧ b ∧ ¬c)
+ E = (¬a ∧ b ∧ c) ∨ (a ∧ ¬b ∧ c) ∨ (a ∧ b ∧ ¬c)
Here it is in action:
::
- ((((((a) (b)) ((b) (c)) ((c) (a))))) ((((a) (b) (c)))))
+ ((((((a) (b)) ((b) (c)) ((c) (a))))) ((((a) (b) (c)))))
equals
::
- (((a (b) (c)) ((a) b (c)) ((a) (b) c)))
+ (((a (b) (c)) ((a) b (c)) ((a) (b) c)))
We can demonstrate this equivalence by evaluating the expression formed
by ``eqiv()`` from these two.
`Half-Bit Adder <https://en.wikipedia.org/wiki/Adder_%28electronics%29#Half_adder>`__
-------------------------------------------------------------------------------------
-If you have two binary digits ("bits") and you are interested in the
+If you have two binary digits (“bits”) and you are interested in the
(binary) sum of these digits you will need two circuits, one for the
-"ones place" and one for the "twos place" or "carry bit".
+“ones place” and one for the “twos place” or “carry bit”.
Consider:
::
- a b | c s
- ----+----
- 0 0 | 0 0
- 0 1 | 0 1
- 1 0 | 0 1
- 1 1 | 1 0
+ a b | c s
+ ----+----
+ 0 0 | 0 0
+ 0 1 | 0 1
+ 1 0 | 0 1
+ 1 1 | 1 0
-Treating each output column ('c' for carry, 's' for sum) as a single
-expression, it's easy to see that the carry bit is just **AND** and the
+Treating each output column (‘c’ for carry, ‘s’ for sum) as a single
+expression, it’s easy to see that the carry bit is just **AND** and the
sum bit is just **XOR** of the two input bits.
.. code:: ipython2
::
- a b Cin Sum Cout
- 0 0 0 | 0 0
- 0 0 1 | 1 0
- 0 1 0 | 1 0
- 0 1 1 | 0 1
- 1 0 0 | 1 0
- 1 0 1 | 0 1
- 1 1 0 | 0 1
- 1 1 1 | 1 1
+ a b Cin Sum Cout
+ 0 0 0 | 0 0
+ 0 0 1 | 1 0
+ 0 1 0 | 1 0
+ 0 1 1 | 0 1
+ 1 0 0 | 1 0
+ 1 0 1 | 0 1
+ 1 1 0 | 0 1
+ 1 1 1 | 1 1
Looking back at our table of three-variable expressions:
::
- ⟶ ( a b c )
- () ⟶ ( a b (c))
- () ⟶ ( a (b) c )
- () () ⟶ ( a (b) (c))
- () ⟶ ((a) b c )
- () () ⟶ ((a) b (c))
- () () ⟶ ((a) (b) c )
- () () () ⟶ ((a) (b) (c))
+ ⟶ ( a b c )
+ () ⟶ ( a b (c))
+ () ⟶ ( a (b) c )
+ () () ⟶ ( a (b) (c))
+ () ⟶ ((a) b c )
+ () () ⟶ ((a) b (c))
+ () () ⟶ ((a) (b) c )
+ () () () ⟶ ((a) (b) (c))
We can easily determine expressions for sum and carry:
::
- Sum = (a b (c)) (a (b) c) ((a) b c) ((a) (b) (c))
+ Sum = (a b (c)) (a (b) c) ((a) b c) ((a) (b) (c))
- Cout = (a (b) (c)) ((a) b (c)) ((a) (b) c) ((a) (b) (c))
+ Cout = (a (b) (c)) ((a) b (c)) ((a) (b) c) ((a) (b) (c))
.. code:: ipython2
() () () | ()
-Let's make a ``full_bit_adder()`` function that can define new
+Let’s make a ``full_bit_adder()`` function that can define new
expressions in terms of variables (or expressions) passed into it.
.. code:: ipython2
::
- S = A ⊕ B ⊕ C
- Cout = (A ⋅ B) + (Cin ⋅ (A ⊕ B))
+ S = A ⊕ B ⊕ C
+ Cout = (A ⋅ B) + (Cin ⋅ (A ⊕ B))
.. code:: ipython2
::
- A((B)) = AB
- A() = ()
- A(AB) = A(B)
+ A((B)) = AB
+ A() = ()
+ A(AB) = A(B)
-I'm going to specify the behaviour of the desired function in a
+I’m going to specify the behaviour of the desired function in a
unittest.
.. code:: ipython2
Three Easy Cases
~~~~~~~~~~~~~~~~
-Let's deal with three easy cases first: string, the Mark, and the Void.
+Let’s deal with three easy cases first: string, the Mark, and the Void.
The ``simplify()`` function should just return them unchanged.
.. code:: ipython2
~~~~~~~~~~~~~~~~~~~~
So far, so good. But what about ``((a))``? This should be returned as
-just ``a``. And ``((a b))`` should remain ``((a b))`` because we can't
+just ``a``. And ``((a b))`` should remain ``((a b))`` because we can’t
represent just ``a b`` as a single Python object, so we have to retain
the outer pair of containers to hold them without inverting the
Mark/Void value (if we just used one container.)
Unwrapping Inner Forms
~~~~~~~~~~~~~~~~~~~~~~
-But now let's trick our function, it can't handle
+But now let’s trick our function, it can’t handle
``(a ((b c))) = (a b c)`` yet. This is going to require an auxiliary
helper function that is similar to ``simplify()`` but that yields terms
into an outer context.
TODO set up `Hypothesis <http://hypothesis.works/>`__ to generate test
-cases...
+cases…
.. code:: ipython2
OK
-`Using "Each-Way" to Simplify Forms <http://www.markability.net/case_analysis.htm>`__
+`Using “Each-Way” to Simplify Forms <http://www.markability.net/case_analysis.htm>`__
-------------------------------------------------------------------------------------
-GSB called this "Each-Way":
+GSB called this “Each-Way”:
::
- a = ((a b) (a (b)))
+ a = ((a b) (a (b)))
.. code:: ipython2
() () | ()
-The form says, "if b then a else a". I'll come back to the
-interpretation of "Each-Way" as an ``if-then-else`` statement later.
+The form says, “if b then a else a”. I’ll come back to the
+interpretation of “Each-Way” as an ``if-then-else`` statement later.
The thing to note here is that the value for ``a`` can be a whole
expression which appears twice in the new form: once next to ``b`` and
::
- b (...(b c (d ...)))
- b (...( c (d ...)))
+ b (...(b c (d ...)))
+ b (...( c (d ...)))
and in the second case we can change any occurances of ``b`` to the
Mark.
::
- (b)(...(b c (d ...)))
- (b)((b)(b c (d ...)))
- (b)(...(b (b) c (d ...)))
- (b)(...(b ( ) c (d ...)))
- (b)(...( ( ) ))
- (b)(... )
+ (b)(...(b c (d ...)))
+ (b)((b)(b c (d ...)))
+ (b)(...(b (b) c (d ...)))
+ (b)(...(b ( ) c (d ...)))
+ (b)(...( ( ) ))
+ (b)(... )
We can send ``(b)`` into the form until it reaches and ``b``, at which
point ``b(b)`` becomes ``()`` and sweeps out any siblings rendering its
(((((b) a) (b)) c) ((c) a b))
-Let's redefine the ``full_bit_adder()`` function with the smallest
+Let’s redefine the ``full_bit_adder()`` function with the smallest
version of each above.
.. code:: ipython2
`Davis–Putnam–Logemann–Loveland (DPLL) algorithm <https://en.wikipedia.org/wiki/Davis%E2%80%93Putnam%E2%80%93Logemann%E2%80%93Loveland_algorithm>`__ SAT Solver
===============================================================================================================================================================
-This is something of an Interlude, we aren't going to use it below, but
-it's too cool to omit mention.
+This is something of an Interlude, we aren’t going to use it below, but
+it’s too cool to omit mention.
We can use the ``simplify()`` function to create a more efficient SAT
solver along the lines of the DPLL algorithm.
with that name first as ``Void`` then as ``Mark``, then recursing with
the new form and the next name. If the resulting simplified form becomes
the ``Mark`` then our choices (of assigning ``Void`` or ``Mark`` to the
-names selected so far) constitute a "solution" to the original form.
+names selected so far) constitute a “solution” to the original form.
That is, if we ``reify()`` the form with the *environment* returned by
the ``dpll()`` function the result will be Mark-valued.
{'a': (), 'b': ()} ((((((()) ())) (c)) ((())))) = ()
-Notice that the reified form still has ``c`` in it but that doesn't
+Notice that the reified form still has ``c`` in it but that doesn’t
prevent the ``simplify()`` function from reducing the form to the Mark.
This should be the case for all solutions generated by the
``dpll_iter()`` function.
::
- (((a5) a5))
- ((( ) a5))
- ((( ) ))
- ( )
- ()
+ (((a5) a5))
+ ((( ) a5))
+ ((( ) ))
+ ( )
+ ()
.. code:: ipython2
Using the Adder Circuits to Add
-------------------------------
-In order to keep things tractable I'm going to use just four bits rather
+In order to keep things tractable I’m going to use just four bits rather
than eight.
.. code:: ipython2
A Model of Computation.
=======================
-That was a bit steep, let's formalize it and make it a little easier to
+That was a bit steep, let’s formalize it and make it a little easier to
work with.
-First let's have a *register* of named values:
+First let’s have a *register* of named values:
.. code:: ipython2
R = {name: Void for name in 'Cin a3 a2 a1 a0 b3 b2 b1 b0 Cout'.split()}
-Let's have a *program* of named expressions that give new values when
+Let’s have a *program* of named expressions that give new values when
evaluated in terms of the current values in **R** (this is just the same
-``CIRCUITS``, but feeding back the results into the "b" bits):
+``CIRCUITS``, but feeding back the results into the “b” bits):
.. code:: ipython2
rr = make_reify_reducer(register)
return {bit: rr(expression) for bit, expression in program.iteritems()}
-With all the register values at "zero" (Void) nothing happens.
+With all the register values at “zero” (Void) nothing happens.
.. code:: ipython2
-Let's make a nice display function to inspect our little adder computer.
+Let’s make a nice display function to inspect our little adder computer.
.. code:: ipython2
a: 0 b: 0 Cin: 0 Cout: 0
-Let's set one bit to true (Mark-valued in the chosen convention. We
+Let’s set one bit to true (Mark-valued in the chosen convention. We
could have Void be true but we would have to form the circuit
expressions differently.)
R['a0'] = Mark
-Now let's count to twenty.
+Now let’s count to twenty.
.. code:: ipython2
a: 1 b: 3 Cin: 0 Cout: 0
-You can see that at the sixteenth step the "Cout" carry bit is true and
+You can see that at the sixteenth step the “Cout” carry bit is true and
the count cycles back to zero.
.. code:: ipython2
a: 3 b: 9 Cin: 0 Cout: 0
-You can see that the "b" bits are indeed counting by threes: 0, 3, 6, 9,
+You can see that the “b” bits are indeed counting by threes: 0, 3, 6, 9,
12, 15 & carry, 2, 5, 8, 11, 14 & carry, 1, 4, 7, 10, 13 & carry, 0, 3,
-6, 9, ...
+6, 9, …
This is my basic model for computation: A register, a program, and a
-cycle function. Note that reducing the form on each cycle isn't
+cycle function. Note that reducing the form on each cycle isn’t
necessary, we can run the cycles and just ``reify()`` without reducing
and we get new circuits that define bits in terms of the register values
N cycles in the past.
A More Efficient Implementation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Before building larger "computers" I want to switch to a more efficient
+Before building larger “computers” I want to switch to a more efficient
implementation based on a register as a ``set`` of names that are
currently Mark-valued, and a ``set_solve()`` function that evaluates a
form in terms of such a ``set``, and assuming all other names are
To calculate the new R first collect all the names in R that are not
mentioned in P (and so cannot be set to Void by it) then add the names
-evaluated by solving P's expressions with the marks in R.
+evaluated by solving P’s expressions with the marks in R.
.. code:: ipython2
return i
return inner
-Each-Way as If... Then...
-~~~~~~~~~~~~~~~~~~~~~~~~~
+Each-Way as If… Then…
+~~~~~~~~~~~~~~~~~~~~~
.. code:: ipython2
::
- w/ a = ()
+ w/ a = ()
- ((( a) b) ( a c))
- (((()) b) (() c))
- (( b) (() ))
- (( b) )
- b
+ ((( a) b) ( a c))
+ (((()) b) (() c))
+ (( b) (() ))
+ (( b) )
+ b
- w/ a =
+ w/ a =
- (((a) b) (a c))
- ((( ) b) ( c))
- ((( ) ) ( c))
- ( ( c))
- c
+ (((a) b) (a c))
+ ((( ) b) ( c))
+ ((( ) ) ( c))
+ ( ( c))
+ c
Flip-Flops for Memory
---------------------
() () () |
-This is a form that can be used in a circuit to "remember" a value.
+This is a form that can be used in a circuit to “remember” a value.
::
- w/ r = ()
+ w/ r = ()
- ((q s) r)
- ((q s) ())
- ( ())
+ ((q s) r)
+ ((q s) ())
+ ( ())
- w/ s = (), r = ___
+ w/ s = (), r = ___
- ((q s) r)
- ((q ()) )
- (( ()) )
- ( )
+ ((q s) r)
+ ((q ()) )
+ (( ()) )
+ ( )
- w/ s = ___, r = ___
+ w/ s = ___, r = ___
- ((q s) r)
- ((q ) )
- q
+ ((q s) r)
+ ((q ) )
+ q
If both are Void then the form is just ``q``, if ``r`` is Mark then the
form is Void, otherwise if ``s`` is Mark the form becomes Mark. This is
-called a "flip-flop" circuit, and it comprises a simple machine to
+called a “flip-flop” circuit, and it comprises a simple machine to
remember one bit.
Consider a simple computer:
You can see that ``q`` is stable unless ``s`` or ``r`` set or reset it.
-Using Flip-Flops and If...Then...Else... to make RAM
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Using Flip-Flops and If…Then…Else… to make RAM
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We can use the system we have developed so far to build addressable RAM.
P = {}
-We'll assume a single ``WRITE`` bit that sets a RAM location determined
+We’ll assume a single ``WRITE`` bit that sets a RAM location determined
by the ``ADDR`` sub-register to the contents of the ``DATA``
sub-register.
::
- A(AB) = A(B)
- ()(()B) = ()(B)
- () = ()
+ A(AB) = A(B)
+ ()(()B) = ()(B)
+ () = ()
w/ A =
::
- A(AB) = A(B)
- (B) = (B)
+ A(AB) = A(B)
+ (B) = (B)
Be aware of the recursive nature of this rule:
::
- A(...(...(A B)))
- A(.A.(...(A B)))
- A(.A.(.A.(A B)))
- A(.A.(.A.( B)))
- A(.A.(...( B)))
- A(...(...( B)))
+ A(...(...(A B)))
+ A(.A.(...(A B)))
+ A(.A.(.A.(A B)))
+ A(.A.(.A.( B)))
+ A(.A.(...( B)))
+ A(...(...( B)))
There is this too:
::
- (A)(...(...(... A B)))
- (A)((A)(...(... A B)))
- (A)((A)((A)(... A B)))
- (A)((A)((A)((A) A B)))
- (A)((A)((A)(( ) A B)))
- (A)((A)(...(( ) )))
- (A)(...(... ))
+ (A)(...(...(... A B)))
+ (A)((A)(...(... A B)))
+ (A)((A)((A)(... A B)))
+ (A)((A)((A)((A) A B)))
+ (A)((A)((A)(( ) A B)))
+ (A)((A)(...(( ) )))
+ (A)(...(... ))
Summarized:
::
- (A)(...(...(... A )))
- (A)(...(...(... () )))
- (A)(...(... ))
+ (A)(...(...(... A )))
+ (A)(...(...(... () )))
+ (A)(...(... ))
Appendix: Reduce String Expressions by Substitution
---------------------------------------------------
``mark()`` uses ``all()``. These functions implement a depth-first
search. If we used versions of ``any()`` and ``all()`` that evaluated
their arguments in parallel ``void()`` could return after the ``True``
-result while ``mark()`` depends on all terms's results so its runtime
+result while ``mark()`` depends on all terms’s results so its runtime
will be bound by term with the greatest runtime.
.. code:: ipython2
::
- (A ∧ ¬B) ∨ (C ∧ D)
+ (A ∧ ¬B) ∨ (C ∧ D)
-(This reads "(A and not B) or (C and D)" in case you have a hard time
+(This reads “(A and not B) or (C and D)” in case you have a hard time
remembering what the symbols mean like I do.)
If we choose Mark to be true then the form is:
::
- ((A) B) ((C)(D))
+ ((A) B) ((C)(D))
If we choose Void to be true then the form is:
::
- ((A (B)) (C D))
+ ((A (B)) (C D))
As I said above, the notation works the same way either way, so once the
translation is made you can forget about the Boolean true/false and just
::
- ¬((¬A ∨ B) ∧ (¬C ∨ ¬D))
+ ¬((¬A ∨ B) ∧ (¬C ∨ ¬D))
If we choose Mark to be true then the form is:
::
- (( ((A) B) ((C)(D)) ))
+ (( ((A) B) ((C)(D)) ))
The outer pair of containers can be deleted leaving the same form as
above:
::
- ((A) B) ((C)(D))
+ ((A) B) ((C)(D))
Likewise, if we choose Void to be true then the form is:
::
- ((((A)) (B)) (((C)) ((D))))
+ ((((A)) (B)) (((C)) ((D))))
Again, A((B)) => AB reduces this form to the same one above:
::
- ((A (B)) (C D))
+ ((A (B)) (C D))
In the Laws of Form there are no De Morgan Dual statements. If you
translate a logic statement and its dual into Laws of Form notation they
# pp.pprint(dict(Counter(yield_variables_of(E))))
# print '------'
-Rather than manually calling ``standard_form()`` let's define a function
+Rather than manually calling ``standard_form()`` let’s define a function
that reduces a form to a (hopefully) smaller equivalent form by going
through all the variables in the form and using ``standard_form()`` with
each. Along with clean and unwrap we can drive an expression to a fixed
different ways to reduce a form to see if it could find particulaly
compact versions.
-Let's generate the expressions for the next two output bits, and the
+Let’s generate the expressions for the next two output bits, and the
carry bit.
The ``sum3`` bit expression is pretty big.
sum3
-But it's only about 1/9th of size of the previous version (which was
+But it’s only about 1/9th of size of the previous version (which was
9261.)
.. code:: ipython2
-Let's simplify the first one manually just for fun:
+Let’s simplify the first one manually just for fun:
::
- (((((())) (())) ((()))))
- (( ) ) ( )
- ( )
+ (((((())) (())) ((()))))
+ (( ) ) ( )
+ ( )
Sure enough, it reduces to Mark after just a few applications of the
rule ``(()) = __`` (the underscores indicates the absence of any value,
::
- ((((a)b)(c)))
- (( ) )( )
- ( )
+ ((((a)b)(c)))
+ (( ) )( )
+ ( )
.. code:: ipython2
Once was enough (we should consider adding a call to ``simplify()`` in
the ``full_bit_adder()`` function.)
-Let's try using ``each_way()`` with the most common names in the form.
+Let’s try using ``each_way()`` with the most common names in the form.
.. code:: ipython2
∂RE
===
-Brzozowski's Derivatives of Regular Expressions
+Brzozowski’s Derivatives of Regular Expressions
-----------------------------------------------
Legend:
::
- ∧ intersection
- ∨ union
- ∘ concatenation (see below)
- ¬ complement
- ϕ empty set (aka ∅)
- λ singleton set containing just the empty string
- I set of all letters in alphabet
+ ∧ intersection
+ ∨ union
+ ∘ concatenation (see below)
+ ¬ complement
+ ϕ empty set (aka ∅)
+ λ singleton set containing just the empty string
+ I set of all letters in alphabet
Derivative of a set ``R`` of strings and a string ``a``:
::
- ∂a(R)
+ ∂a(R)
- ∂a(a) → λ
- ∂a(λ) → ϕ
- ∂a(ϕ) → ϕ
- ∂a(¬a) → ϕ
- ∂a(R*) → ∂a(R)∘R*
- ∂a(¬R) → ¬∂a(R)
- ∂a(R∘S) → ∂a(R)∘S ∨ δ(R)∘∂a(S)
- ∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
- ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
+ ∂a(a) → λ
+ ∂a(λ) → ϕ
+ ∂a(ϕ) → ϕ
+ ∂a(¬a) → ϕ
+ ∂a(R*) → ∂a(R)∘R*
+ ∂a(¬R) → ¬∂a(R)
+ ∂a(R∘S) → ∂a(R)∘S ∨ δ(R)∘∂a(S)
+ ∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
+ ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
- ∂ab(R) = ∂b(∂a(R))
+ ∂ab(R) = ∂b(∂a(R))
Auxiliary predicate function ``δ`` (I call it ``nully``) returns either
``λ`` if ``λ ⊆ R`` or ``ϕ`` otherwise:
::
- δ(a) → ϕ
- δ(λ) → λ
- δ(ϕ) → ϕ
- δ(R*) → λ
- δ(¬R) δ(R)≟ϕ → λ
- δ(¬R) δ(R)≟λ → ϕ
- δ(R∘S) → δ(R) ∧ δ(S)
- δ(R ∧ S) → δ(R) ∧ δ(S)
- δ(R ∨ S) → δ(R) ∨ δ(S)
+ δ(a) → ϕ
+ δ(λ) → λ
+ δ(ϕ) → ϕ
+ δ(R*) → λ
+ δ(¬R) δ(R)≟ϕ → λ
+ δ(¬R) δ(R)≟λ → ϕ
+ δ(R∘S) → δ(R) ∧ δ(S)
+ δ(R ∧ S) → δ(R) ∧ δ(S)
+ δ(R ∨ S) → δ(R) ∨ δ(S)
-Some rules we will use later for "compaction":
+Some rules we will use later for “compaction”:
::
- R ∧ ϕ = ϕ ∧ R = ϕ
+ R ∧ ϕ = ϕ ∧ R = ϕ
- R ∧ I = I ∧ R = R
+ R ∧ I = I ∧ R = R
- R ∨ ϕ = ϕ ∨ R = R
+ R ∨ ϕ = ϕ ∨ R = R
- R ∨ I = I ∨ R = I
+ R ∨ I = I ∨ R = I
- R∘ϕ = ϕ∘R = ϕ
+ R∘ϕ = ϕ∘R = ϕ
- R∘λ = λ∘R = R
+ R∘λ = λ∘R = R
Concatination of sets: for two sets A and B the set A∘B is defined as:
E.g.:
-{'a', 'b'}∘{'c', 'd'} → {'ac', 'ad', 'bc', 'bd'}
+{‘a’, ‘b’}∘{‘c’, ‘d’} → {‘ac’, ‘ad’, ‘bc’, ‘bd’}
Implementation
--------------
Two-letter Alphabet
~~~~~~~~~~~~~~~~~~~
-I'm only going to use two symbols (at first) becaase this is enough to
+I’m only going to use two symbols (at first) becaase this is enough to
illustrate the algorithm and because you can represent any other
alphabet with two symbols (if you had to.)
-I chose the names ``O`` and ``l`` (uppercase "o" and lowercase "L") to
+I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
look like ``0`` and ``1`` (zero and one) respectively.
.. code:: ipython2
Representing Regular Expressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-To represent REs in Python I'm going to use tagged tuples. A *regular
+To represent REs in Python I’m going to use tagged tuples. A *regular
expression* is one of:
::
- O
- l
- (KSTAR, R)
- (NOT, R)
- (AND, R, S)
- (CONS, R, S)
- (OR, R, S)
+ O
+ l
+ (KSTAR, R)
+ (NOT, R)
+ (AND, R, S)
+ (CONS, R, S)
+ (OR, R, S)
Where ``R`` and ``S`` stand for *regular expressions*.
``I``
~~~~~
-Match anything. Often spelled "."
+Match anything. Often spelled “.”
::
- I = (0|1)*
+ I = (0|1)*
.. code:: ipython2
::
- (.111.) & (.01 + 11*)'
- a & (b + c)'
+ (.111.) & (.01 + 11*)'
+ a & (b + c)'
Note that it contains one of everything.
``nully()``
~~~~~~~~~~~
-Let's get that auxiliary predicate function ``δ`` out of the way.
+Let’s get that auxiliary predicate function ``δ`` out of the way.
.. code:: ipython2
r, s = nully(R[1]), nully(R[2])
return r & s if tag in {AND, CONS} else r | s
-No "Compaction"
+No “Compaction”
~~~~~~~~~~~~~~~
-This is the straightforward version with no "compaction". It works fine,
+This is the straightforward version with no “compaction”. It works fine,
but does waaaay too much work because the expressions grow each
derivation.
result = self.mem[key] = self.f(key)
return result
-With "Compaction"
+With “Compaction”
~~~~~~~~~~~~~~~~~
This version uses the rules above to perform compaction. It keeps the
return derv
-Let's try it out...
--------------------
+Let’s try it out…
+-----------------
(FIXME: redo.)
::
- (.111.) & ((.01 | 11*)')
+ (.111.) & ((.01 | 11*)')
- 92 / 122
- 92 / 122
+ 92 / 122
+ 92 / 122
- (.01 )'
- (.01 | 1 )'
- (.01 | ^ )'
- (.01 | 1*)'
- (.111.) & ((.01 | 1 )')
- (.111. | 11.) & ((.01 | ^ )')
- (.111. | 11.) & ((.01 | 1*)')
- (.111. | 11. | 1.) & ((.01 )')
- (.111. | 11. | 1.) & ((.01 | 1*)')
+ (.01 )'
+ (.01 | 1 )'
+ (.01 | ^ )'
+ (.01 | 1*)'
+ (.111.) & ((.01 | 1 )')
+ (.111. | 11.) & ((.01 | ^ )')
+ (.111. | 11.) & ((.01 | 1*)')
+ (.111. | 11. | 1.) & ((.01 )')
+ (.111. | 11. | 1.) & ((.01 | 1*)')
Larger Alphabets
----------------
-We could parse larger alphabets by defining patterns for e.g. each byte
+We could parse larger alphabets by defining patterns for e.g. each byte
of the ASCII code. Or we can generalize this code. If you study the code
-above you'll see that we never use the "set-ness" of the symbols ``O``
+above you’ll see that we never use the “set-ness” of the symbols ``O``
and ``l``. The only time Python set operators (``&`` and ``|``) appear
is in the ``nully()`` function, and there they operate on (recursively
computed) outputs of that function, never ``O`` and ``l``.
::
- (OR, O, l)
+ (OR, O, l)
- ∂1((OR, O, l))
- ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
- ∂1(O) ∨ ∂1(l)
- ∂a(¬a) → ϕ
- ϕ ∨ ∂1(l)
- ∂a(a) → λ
- ϕ ∨ λ
- ϕ ∨ R = R
- λ
+ ∂1((OR, O, l))
+ ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
+ ∂1(O) ∨ ∂1(l)
+ ∂a(¬a) → ϕ
+ ϕ ∨ ∂1(l)
+ ∂a(a) → λ
+ ϕ ∨ λ
+ ϕ ∨ R = R
+ λ
And compare it to:
::
- {'0', '1')
+ {'0', '1')
- ∂1({'0', '1'))
- ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
- ∂1({'0')) ∨ ∂1({'1'))
- ∂a(¬a) → ϕ
- ϕ ∨ ∂1({'1'))
- ∂a(a) → λ
- ϕ ∨ λ
- ϕ ∨ R = R
- λ
+ ∂1({'0', '1'))
+ ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
+ ∂1({'0')) ∨ ∂1({'1'))
+ ∂a(¬a) → ϕ
+ ϕ ∨ ∂1({'1'))
+ ∂a(a) → λ
+ ϕ ∨ λ
+ ϕ ∨ R = R
+ λ
This suggests that we should be able to alter the functions above to
detect sets and deal with them appropriately. Exercise for the Reader
::
- .111. & (.01 + 11*)'
+ .111. & (.01 + 11*)'
-Says, "Three or more 1's and not ending in 01 nor composed of all 1's."
+Says, “Three or more 1’s and not ending in 01 nor composed of all 1’s.”
.. figure:: attachment:omg.svg
:alt: omg.svg
Start at ``a`` and follow the transition arrows according to their
labels. Accepting states have a double outline. (Graphic generated with
-`Dot from Graphviz <http://www.graphviz.org/>`__.) You'll see that only
+`Dot from Graphviz <http://www.graphviz.org/>`__.) You’ll see that only
paths that lead to one of the accepting states will match the regular
expression. All other paths will terminate at one of the non-accepting
states.
-There's a happy path to ``g`` along 111:
+There’s a happy path to ``g`` along 111:
::
- a→c→e→g
+ a→c→e→g
-After you reach ``g`` you're stuck there eating 1's until you see a 0,
-which takes you to the ``i→j→i|i→j→h→i`` "trap". You can't reach any
+After you reach ``g`` you’re stuck there eating 1’s until you see a 0,
+which takes you to the ``i→j→i|i→j→h→i`` “trap”. You can’t reach any
other states from those two loops.
If you see a 0 before you see 111 you will reach ``b``, which forms
-another "trap" with ``d`` and ``f``. The only way out is another happy
+another “trap” with ``d`` and ``f``. The only way out is another happy
path along 111 to ``h``:
::
- b→d→f→h
+ b→d→f→h
-Once you have reached ``h`` you can see as many 1's or as many 0' in a
-row and still be either still at ``h`` (for 1's) or move to ``i`` (for
-0's). If you find yourself at ``i`` you can see as many 0's, or
+Once you have reached ``h`` you can see as many 1’s or as many 0’ in a
+row and still be either still at ``h`` (for 1’s) or move to ``i`` (for
+0’s). If you find yourself at ``i`` you can see as many 0’s, or
repetitions of 10, as there are, but if you see just a 1 you move to
``j``.
So how do we get the state machine from the regular expression?
It turns out that each RE is effectively a state, and each arrow points
-to the derivative RE in respect to the arrow's symbol.
+to the derivative RE in respect to the arrow’s symbol.
If we label the initial RE ``a``, we can say:
::
- a --0--> ∂0(a)
- a --1--> ∂1(a)
+ a --0--> ∂0(a)
+ a --1--> ∂1(a)
And so on, each new unique RE is a new state in the FSM table.
::
- a = (.111.) & ((.01 | 11*)')
- b = (.111.) & ((.01 | 1)')
- c = (.111. | 11.) & ((.01 | 1*)')
- d = (.111. | 11.) & ((.01 | ^)')
- e = (.111. | 11. | 1.) & ((.01 | 1*)')
- f = (.111. | 11. | 1.) & ((.01)')
- g = (.01 | 1*)'
- h = (.01)'
- i = (.01 | 1)'
- j = (.01 | ^)'
-
-You can see the one-way nature of the ``g`` state and the ``hij`` "trap"
+ a = (.111.) & ((.01 | 11*)')
+ b = (.111.) & ((.01 | 1)')
+ c = (.111. | 11.) & ((.01 | 1*)')
+ d = (.111. | 11.) & ((.01 | ^)')
+ e = (.111. | 11. | 1.) & ((.01 | 1*)')
+ f = (.111. | 11. | 1.) & ((.01)')
+ g = (.01 | 1*)'
+ h = (.01)'
+ i = (.01 | 1)'
+ j = (.01 | ^)'
+
+You can see the one-way nature of the ``g`` state and the ``hij`` “trap”
in the way that the ``.111.`` on the left-hand side of the ``&``
disappears once it has been matched.
There are *lots* of FSM libraries already. Once you have the state
transition table they should all be straightforward to use. State
Machine code is very simple. Just for fun, here is an implementation in
-Python that imitates what "compiled" FSM code might look like in an
-"unrolled" form. Most FSM code uses a little driver loop and a table
+Python that imitates what “compiled” FSM code might look like in an
+“unrolled” form. Most FSM code uses a little driver loop and a table
datastructure, the code below instead acts like JMP instructions
-("jump", or GOTO in higher-level-but-still-low-level languages) to
+(“jump”, or GOTO in higher-level-but-still-low-level languages) to
hard-code the information in the table into a little patch of branches.
Trampoline Function
^^^^^^^^^^^^^^^^^^^
-Python has no GOTO statement but we can fake it with a "trampoline"
+Python has no GOTO statement but we can fake it with a “trampoline”
function.
.. code:: ipython2
Stream Functions
^^^^^^^^^^^^^^^^
-Little helpers to process the iterator of our data (a "stream" of "1"
-and "0" characters, not bits.)
+Little helpers to process the iterator of our data (a “stream” of “1”
+and “0” characters, not bits.)
.. code:: ipython2
Note that the implementations of ``h`` and ``g`` are identical ergo
``h = g`` and we could eliminate one in the code but ``h`` is an
-accepting state and ``g`` isn't.
+accepting state and ``g`` isn’t.
.. code:: ipython2
------------------------------------------------------
(UNFINISHED) Brzozowski also shewed how to go from the state machine to
-strings and expressions...
+strings and expressions…
Each of these states is just a name for a Brzozowskian RE, and so, other
than the initial state ``a``, they can can be described in terms of the
::
- c = d1(a)
- b = d0(a)
- b = d0(c)
- ...
- i = d0(j)
- j = d1(i)
+ c = d1(a)
+ b = d0(a)
+ b = d0(c)
+ ...
+ i = d0(j)
+ j = d1(i)
Consider:
::
- c = d1(a)
- b = d0(c)
+ c = d1(a)
+ b = d0(c)
Substituting:
::
- b = d0(d1(a))
+ b = d0(d1(a))
Unwrapping:
::
- b = d10(a)
+ b = d10(a)
-'''
+’’’
::
- j = d1(d0(j))
+ j = d1(d0(j))
Unwrapping:
::
- j = d1(d0(j)) = d01(j)
+ j = d1(d0(j)) = d01(j)
-We have a loop or "fixed point".
+We have a loop or “fixed point”.
::
- j = d01(j) = d0101(j) = d010101(j) = ...
+ j = d01(j) = d0101(j) = d010101(j) = ...
-hmm...
+hmm…
::
- j = (01)*
+ j = (01)*
::
- x == dup i
+ x == dup i
We can apply it to a quoted program consisting of some value ``a`` and
some function ``B``:
::
- [a B] x
- [a B] a B
+ [a B] x
+ [a B] a B
Let ``B`` function ``swap`` the ``a`` with the quote and run some
function ``C`` on it to generate a new value ``b``:
::
- B == swap [C] dip
+ B == swap [C] dip
- [a B] a B
- [a B] a swap [C] dip
- a [a B] [C] dip
- a C [a B]
- b [a B]
+ [a B] a B
+ [a B] a swap [C] dip
+ a [a B] [C] dip
+ a C [a B]
+ b [a B]
Now discard the quoted ``a`` with ``rest`` then ``cons`` ``b``:
::
- b [a B] rest cons
- b [B] cons
- [b B]
+ b [a B] rest cons
+ b [B] cons
+ [b B]
Altogether, this is the definition of ``B``:
::
- B == swap [C] dip rest cons
+ B == swap [C] dip rest cons
-We can make a generator for the Natural numbers (0, 1, 2, ...) by using
+We can make a generator for the Natural numbers (0, 1, 2, …) by using
``0`` for ``a`` and ``[dup ++]`` for ``[C]``:
::
- [0 swap [dup ++] dip rest cons]
+ [0 swap [dup ++] dip rest cons]
-Let's try it:
+Let’s try it:
.. code:: ipython2
::
- a [C] G
- -------------------------
- [a swap [C] direco]
+ a [C] G
+ -------------------------
+ [a swap [C] direco]
Working in reverse:
::
- [a swap [C] direco] cons
- a [swap [C] direco] concat
- a [swap] [[C] direco] swap
- a [[C] direco] [swap]
- a [C] [direco] cons [swap]
+ [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
+ G == [direco] cons [swap] swap concat cons
+ G == [direco] cons [swap] swoncat cons
.. code:: ipython2
define('G == [direco] cons [swap] swoncat cons')
-Let's try it out:
+Let’s try it out:
.. code:: ipython2
--------------------------------------
Look at the treatment of the Project Euler Problem One in the
-"Developing a Program" notebook and you'll see that we might be
+“Developing a Program” notebook and you’ll see that we might be
interested in generating an endless cycle of:
::
- 3 2 1 3 1 2 3
+ 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
+ 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.
3 3702 .
-If we plug ``14811`` and ``[PE1.1]`` into our generator form...
+If we plug ``14811`` and ``[PE1.1]`` into our generator form…
.. code:: ipython2
[14811 swap [PE1.1] direco]
-...we get a generator that works for seven cycles before it reaches
-zero:
+…we get a generator that works for seven cycles before it reaches zero:
.. code:: ipython2
(It would be more efficient to reset the int every seven cycles but
-that's a little beyond the scope of this article. This solution does
-extra work, but not much, and we're not using it "in production" as they
+that’s a little beyond the scope of this article. This solution does
+extra work, but not much, and we’re not using it “in production” as they
say.)
Run 466 times
~~~~~~~~~~~~~
In the PE1 problem we are asked to sum all the multiples of three and
-five less than 1000. It's worked out that we need to use all seven
+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
::
- [b a F] x
- [b a F] b a F
+ [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
+ [b a F] b a +
+ [b a F] b+a
From here we want to arrive at:
::
- b [b+a b F]
+ b [b+a b F]
-Let's start with ``swons``:
+Let’s start with ``swons``:
::
- [b a F] b+a swons
- [b+a b a F]
+ [b a F] b+a swons
+ [b+a b a F]
Considering this quote as a stack:
::
- F a b b+a
+ F a b b+a
We want to get it to:
::
- F b b+a b
+ F b b+a b
So:
::
- F a b b+a popdd over
- F b b+a b
+ 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]
+ [b+a b a F] [popdd over] infra
+ [b b+a b F]
But we can just use ``cons`` to carry ``b+a`` into the quote:
::
- [b a F] b+a [popdd over] cons infra
- [b a F] [b+a popdd over] infra
- [b b+a b F]
+ [b a F] b+a [popdd over] cons infra
+ [b a F] [b+a popdd over] infra
+ [b b+a b F]
Lastly:
::
- [b b+a b F] uncons
- b [b+a b F]
+ [b b+a b F] uncons
+ b [b+a b F]
Putting it all together:
::
- F == + [popdd over] cons infra uncons
- fib_gen == [1 1 F]
+ F == + [popdd over] cons infra uncons
+ fib_gen == [1 1 F]
.. code:: ipython2
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.
+ 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
define('PE2.1 == dup 2 % [+] [pop] branch')
And a predicate function that detects when the terms in the series
-"exceed four million".
+“exceed four million”.
.. code:: ipython2
define('>4M == 4000000 >')
-Now it's straightforward to define ``PE2`` as a recursive function that
+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.
4613732
-Here's the collected program definitions:
+Here’s the collected program definitions:
::
- fib == + swons [popdd over] infra uncons
- fib_gen == [1 1 fib]
+ fib == + swons [popdd over] infra uncons
+ fib_gen == [1 1 fib]
- even == dup 2 %
- >4M == 4000000 >
+ even == dup 2 %
+ >4M == 4000000 >
- PE2.1 == even [+] [pop] branch
- PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
+ PE2.1 == even [+] [pop] branch
+ PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
Even-valued Fibonacci Terms
~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- o + o = e
- e + e = e
- o + e = o
+ 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 . . .
+ 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.
-Cf. `"Bananas, Lenses, & Barbed
-Wire" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
+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 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".
+- 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.
Finding `Triangular Numbers <https://en.wikipedia.org/wiki/Triangular_number>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-As a concrete example let's use a function that, given a positive
+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()``
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".
+meant by “call stack in the form of a cons list”.
Joy Preamble
~~~~~~~~~~~~
::
- H == c [F] [P] [G] hylomorphism
+ 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 == [P] [pop c] [J] ifte
+ 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.
+ 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
+ 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
+ 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
+ H == [P] [pop c] [G] [dip F] genrec
Derivation of ``hylomorphism``
------------------------------
::
- 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
+ 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
::
- hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
+ 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
::
- [P] c [G] [F] hylomorphism == H
+ [P] c [G] [F] hylomorphism == H
.. code:: ipython2
::
- [P] [G] anamorphism == [P] [] [G] [swons] hylomorphism == A
+ [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
+ [] swap [swons] hylomorphism == anamorphism
-Partial evaluation gives us a "pre-cooked" form.
+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] [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
+ [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
+ 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
::
- [P] [G] [pop []] swap [dip swons] genrec
+ [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
+ anamorphism == [pop []] swap [dip swons] genrec
An example of an anamorphism is the range function.
::
- range == [0 <=] [1 - dup] anamorphism
+ range == [0 <=] [1 - dup] anamorphism
Catamorphism
============
::
- c [F] catamorphism == [[] =] c [uncons swap] [F] hylomorphism == C
+ 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
+ [[] =] roll> [uncons swap] swap hylomorphism == catamorphism
-Partial evaluation doesn't help much.
+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
+ 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.
+there isn’t much point to “pre-cooking” the definition.
::
- catamorphism == [[] =] roll> [uncons swap] swap hylomorphism
+ catamorphism == [[] =] roll> [uncons swap] swap hylomorphism
An example of a catamorphism is the sum function.
::
- sum == 0 [+] catamorphism
+ sum == 0 [+] catamorphism
-"Fusion Law" for catas (UNFINISHED!!!)
+“Fusion Law” for catas (UNFINISHED!!!)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-I'm not sure exactly how to translate the "Fusion Law" for catamorphisms
+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
::
- [F] map b [B] cata == b [F B] cata
+ [F] map b [B] cata == b [F B] cata
-But this isn't the one described in "Bananas...". That's more like:
+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
+ b [B] catamorphism F == c [C] catamorphism
Given:
::
- b F == c
+ b F == c
- ...
+ ...
- B F == [F] dip C
+ B F == [F] dip C
- ...
+ ...
- b[B]cata F == c[C]cata
+ b[B]cata F == c[C]cata
- F(B(head, tail)) == C(head, F(tail))
+ F(B(head, tail)) == C(head, F(tail))
- 1 [2 3] B F 1 [2 3] F C
+ 1 [2 3] B F 1 [2 3] F C
- b F == c
- B F == F C
+ b F == c
+ B F == F C
- b [B] catamorphism F == c [C] catamorphism
- b [B] catamorphism F == b F [C] catamorphism
+ 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 == 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
+ [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
+ [10 *] map 0 swap [+] step == 0 swap [10 * +] step
For example:
::
- F == 10 *
- b == 0
- B == +
- c == 0
- C == F +
+ F == 10 *
+ b == 0
+ B == +
+ c == 0
+ C == F +
- b F == c
- 0 10 * == 0
+ b F == c
+ 0 10 * == 0
- B F == [F] dip C
- + 10 * == [10 *] dip F +
- + 10 * == [10 *] dip 10 * +
+ B F == [F] dip C
+ + 10 * == [10 *] dip F +
+ + 10 * == [10 *] dip 10 * +
- n m + 10 * == 10(n+m)
+ n m + 10 * == 10(n+m)
- n m [10 *] dip 10 * +
- n 10 * m 10 * +
- 10n m 10 * +
- 10n 10m +
- 10n+10m
+ n m [10 *] dip 10 * +
+ n 10 * m 10 * +
+ 10n m 10 * +
+ 10n 10m +
+ 10n+10m
- 10n+10m = 10(n+m)
+ 10n+10m = 10(n+m)
Ergo:
::
- 0 [+] catamorphism 10 * == 0 [10 * +] catamorphism
+ 0 [+] catamorphism 10 * == 0 [10 * +] catamorphism
The ``step`` combinator will usually be better to use than ``catamorphism``.
----------------------------------------------------------------------------
::
- sum == 0 swap [+] step
- sum == 0 [+] catamorphism
+ sum == 0 swap [+] step
+ sum == 0 [+] catamorphism
anamorphism catamorphism == hylomorphism
========================================
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
+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 == [0 <=] [1 - dup] anamorphism
+ sum == 0 [+] catamorphism
- range sum == [0 <=] [1 - dup] anamorphism 0 [+] catamorphism
- == [0 <=] 0 [1 - dup] [+] hylomorphism
+ 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
+ H == [P] [pop c] [G] [dip F] genrec
+ range_sum == [0 <=] [pop 0] [1 - dup] [dip +] genrec
.. code:: ipython2
::
- n swap [P] [pop] [[F] dupdip G] primrec
+ n swap [P] [pop] [[F] dupdip G] primrec
-With - ``n :: A`` is the "identity" for ``F`` (like 1 for
+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.
::
- n == 1
- F == *
- G == --
- P == 1 <=
+ n == 1
+ F == *
+ G == --
+ P == 1 <=
.. code:: ipython2
::
- 3 1 swap [1 <=] [pop] [[*] dupdip --] primrec
- 1 3 [1 <=] [pop] [[*] dupdip --] primrec
+ 3 1 swap [1 <=] [pop] [[*] dupdip --] primrec
+ 1 3 [1 <=] [pop] [[*] dupdip --] primrec
- 1 3 [*] dupdip --
- 1 3 * 3 --
- 3 3 --
- 3 2
+ 1 3 [*] dupdip --
+ 1 3 * 3 --
+ 3 3 --
+ 3 2
- 3 2 [*] dupdip --
- 3 2 * 2 --
- 6 2 --
- 6 1
+ 3 2 [*] dupdip --
+ 3 2 * 2 --
+ 6 2 --
+ 6 1
- 6 1 [1 <=] [pop] [[*] dupdip --] primrec
+ 6 1 [1 <=] [pop] [[*] dupdip --] primrec
- 6 1 pop
- 6
+ 6 1 pop
+ 6
.. code:: ipython2
::
- n swap [P] [pop] [[F] dupdip G] primrec
+ 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
+ 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
+ paramorphism == [dupdip] swoncat cons [[swap] dip [pop]] dip primrec
.. code:: ipython2
``tails``
=========
-An example of a paramorphism for lists given in the `"Bananas..."
+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.
+is ``tails`` which returns the list of “tails” of a list.
::
- [1 2 3] tails == [[] [3] [2 3]]
+ [1 2 3] tails == [[] [3] [2 3]]
Using ``paramorphism`` we would write:
::
- n == []
- F == rest swons
- G == rest
- P == not
+ n == []
+ F == rest swons
+ G == rest
+ P == not
- tails == [] [not] [rest swons] [rest] paramorphism
+ tails == [] [not] [rest swons] [rest] paramorphism
.. code:: ipython2
::
- [] [1 2 3] [not] [pop] [[rest swons] dupdip rest] primrec
+ [] [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
+ [] [1 2 3] [not] [pop] [rest [swons] dupdip] primrec
-There's no way to do that with the ``paramorphism`` combinator as
+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]``
+combinator that accepted an additional “preprocessor” function ``[H]``
and built:
::
- n swap [P] [pop] [H [F] dupdip G] primrec
+ 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
Patterns of Recursion
=====================
-Our story so far...
+Our story so far…
- A combiner ``F :: (B, B) -> B``
- A predicate ``P :: A -> Bool`` to detect the base case
::
- w/ G :: A -> (A, B)
+ 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
+ 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
+ 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
+ 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
+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.
+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
+ 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'
+ ... 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
+ 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
+ ... 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.
+continuation “collapses” into the final result.
2
~
::
- 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
+ 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
::
- 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
+ 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
~
::
- 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
+ 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.
::
- H == [P ] [pop c ] [G ] [dip F ] genrec
+ H == [P ] [pop c ] [G ] [dip F ] genrec
.. code:: ipython2
::
- |[ (c, F), (G, P) ]| == (|c, F|) • [(G, P)]
+ |[ (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>`__
+`“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."
+“Too much is always better than not enough.”
-`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
+`Newton’s method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
=====================================================================
-Let's use the Newton-Raphson method for finding the root of an equation
+Let’s use the Newton-Raphson method for finding the root of an equation
to write a function that can compute the square root of a number.
-Cf. `"Why Functional Programming Matters" by John
+Cf. `“Why Functional Programming Matters” by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
.. code:: ipython2
::
- a F
- ---------
- a'
+ a F
+ ---------
+ a'
A Function to Compute the Next Approximation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- a n over / + 2 /
- a n a / + 2 /
- a n/a + 2 /
- a+n/a 2 /
- (a+n/a)/2
+ a n over / + 2 /
+ a n a / + 2 /
+ a n/a + 2 /
+ a+n/a 2 /
+ (a+n/a)/2
The function we want has the argument ``n`` in it:
::
- F == n over / + 2 /
+ F == n over / + 2 /
Make it into a Generator
~~~~~~~~~~~~~~~~~~~~~~~~
::
- a [dup F] make_generator
+ a [dup F] make_generator
With n as part of the function F, but n is the input to the sqrt
function we’re writing. If we let 1 be the initial approximation:
::
- 1 n 1 / + 2 /
- 1 n/1 + 2 /
- 1 n + 2 /
- n+1 2 /
- (n+1)/2
+ 1 n 1 / + 2 /
+ 1 n/1 + 2 /
+ 1 n + 2 /
+ n+1 2 /
+ (n+1)/2
The generator can be written as:
::
- 23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
- 1 23 [over / + 2 /] cons [dup] swoncat make_generator
- 1 [23 over / + 2 /] [dup] swoncat make_generator
- 1 [dup 23 over / + 2 /] make_generator
+ 23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
+ 1 23 [over / + 2 /] cons [dup] swoncat make_generator
+ 1 [23 over / + 2 /] [dup] swoncat make_generator
+ 1 [dup 23 over / + 2 /] make_generator
.. code:: ipython2
[1 [dup 23 over / + 2 /] codireco]
-Let's drive the generator a few time (with the ``x`` combinator) and
-square the approximation to see how well it works...
+Let’s drive the generator a few time (with the ``x`` combinator) and
+square the approximation to see how well it works…
.. code:: ipython2
Finding Consecutive Approximations within a Tolerance
-----------------------------------------------------
-From `"Why Functional Programming Matters" by John
+From `“Why Functional Programming Matters” by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__:
- The remainder of a square root finder is a function *within*, which
- takes a tolerance and a list of approximations and looks down the
- list for two successive approximations that differ by no more than
- the given tolerance.
+ The remainder of a square root finder is a function *within*, which
+ takes a tolerance and a list of approximations and looks down the
+ list for two successive approximations that differ by no more than
+ the given tolerance.
(And note that by “list” he means a lazily-evaluated list.)
Using the *output* ``[a G]`` of the above generator for square root
approximations, and further assuming that the first term a has been
-generated already and epsilon ε is handy on the stack...
+generated already and epsilon ε is handy on the stack…
::
- a [b G] ε within
- ---------------------- a b - abs ε <=
- b
+ a [b G] ε within
+ ---------------------- a b - abs ε <=
+ b
- a [b G] ε within
- ---------------------- a b - abs ε >
- b [c G] ε within
+ a [b G] ε within
+ ---------------------- a b - abs ε >
+ b [c G] ε within
Predicate
~~~~~~~~~
::
- a [b G] ε [first - abs] dip <=
- a [b G] first - abs ε <=
- a b - abs ε <=
- a-b abs ε <=
- abs(a-b) ε <=
- (abs(a-b)<=ε)
+ a [b G] ε [first - abs] dip <=
+ a [b G] first - abs ε <=
+ a b - abs ε <=
+ a-b abs ε <=
+ abs(a-b) ε <=
+ (abs(a-b)<=ε)
.. code:: ipython2
::
- a [b G] ε roll< popop first
- [b G] ε a popop first
- [b G] first
- b
+ a [b G] ε roll< popop first
+ [b G] ε a popop first
+ [b G] first
+ b
.. code:: ipython2
::
- a [b G] ε R0 [within] R1
+ a [b G] ε R0 [within] R1
1. Discard a.
2. Use ``x`` combinator to generate next term from ``G``.
::
- a [b G] ε R0 [within] R1
- a [b G] ε [popd x] dip [within] i
- a [b G] popd x ε [within] i
- [b G] x ε [within] i
- b [c G] ε [within] i
- b [c G] ε within
+ a [b G] ε R0 [within] R1
+ a [b G] ε [popd x] dip [within] i
+ a [b G] popd x ε [within] i
+ [b G] x ε [within] i
+ b [c G] ε [within] i
+ b [c G] ε within
- b [c G] ε within
+ b [c G] ε within
.. code:: ipython2
::
- [a G] x ε ...
- a [b G] ε ...
+ [a G] x ε ...
+ a [b G] ε ...
.. code:: ipython2
define('within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec')
define('sqrt == gsra within')
-Try it out...
+Try it out…
.. code:: ipython2
::
- Tree :: [] | [key value Tree Tree]
+ Tree :: [] | [key value Tree Tree]
That says that a Tree is either the empty quote ``[]`` or a quote with
four items: a key, a value, and two Trees representing the left and
right branches of the tree.
-We're going to derive some recursive functions to work with such
+We’re going to derive some recursive functions to work with such
datastructures:
::
- Tree-add
- Tree-delete
- Tree-get
- Tree-iter
- Tree-iter-order
+ Tree-add
+ Tree-delete
+ Tree-get
+ Tree-iter
+ Tree-iter-order
-Once these functions are defined we have a new "type" to work with, and
+Once these functions are defined we have a new “type” to work with, and
the Sufficiently Smart Compiler can be modified to use an optimized
-implementation under the hood. (Where does the "type" come from? It has
+implementation under the hood. (Where does the “type” come from? It has
a contingent existence predicated on the disciplined use of these
functions on otherwise undistinguished Joy datastructures.)
Adding Nodes to the Tree
------------------------
-Let's consider adding nodes to a Tree structure.
+Let’s consider adding nodes to a Tree structure.
::
- Tree value key Tree-add
- -----------------------------
- Tree′
+ Tree value key Tree-add
+ -----------------------------
+ Tree′
Adding to an empty node.
~~~~~~~~~~~~~~~~~~~~~~~~
::
- Tree-add == [popop not] [[pop] dipd Tree-new] [R0] [R1] genrec
+ Tree-add == [popop not] [[pop] dipd Tree-new] [R0] [R1] genrec
``Tree-new``
^^^^^^^^^^^^
::
- value key Tree-new
- ------------------------
- [key value [] []]
+ value key Tree-new
+ ------------------------
+ [key value [] []]
Example:
::
- value key swap [[] []] cons cons
- key value [[] []] cons cons
- key [value [] []] cons
- [key value [] []]
+ value key swap [[] []] cons cons
+ key value [[] []] cons cons
+ key [value [] []] cons
+ [key value [] []]
Definition:
::
- Tree-new == swap [[] []] cons cons
+ Tree-new == swap [[] []] cons cons
.. code:: ipython2
(As an implementation detail, the ``[[] []]`` literal used in the
definition of ``Tree-new`` will be reused to supply the *constant* tail
for *all* new nodes produced by it. This is one of those cases where you
-get amortized storage "for free" by using `persistent
+get amortized storage “for free” by using `persistent
datastructures <https://en.wikipedia.org/wiki/Persistent_data_structure>`__.
Because the tail, which is ``((), ((), ()))`` in Python, is immutable
and embedded in the definition body for ``Tree-new``, all new nodes can
::
- [key_n value_n left right] value key R0 [Tree-add] R1
+ [key_n value_n left right] value key R0 [Tree-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
+less than or equal to the node’s key. In two of those cases we will need
to apply a copy of ``Tree-add``, so ``R0`` is pretty much out of the
picture.
::
- [R0] == []
+ [R0] == []
A predicate to compare keys.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [key_n value_n left right] value key [BTree-add] R1
+ [key_n value_n left right] value key [BTree-add] R1
-The first thing we need to do is compare the the key we're adding to the
+The first thing we need to do is compare the the key we’re adding to the
node key and ``branch`` accordingly:
::
- [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] [T] [E] ifte
That would suggest something like:
::
- [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
+ [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
-Let's abstract the predicate just a little to let us specify the
+Let’s abstract the predicate just a little to let us specify the
comparison operator:
::
- P > == pop roll> pop first >
- P < == pop roll> pop first <
- P == pop roll> pop first
+ P > == pop roll> pop first >
+ P < == pop roll> pop first <
+ P == pop roll> pop first
.. code:: ipython2
'new_key' 'old_key'
-If the key we're adding is greater than the node's key.
+If the key we’re adding is greater than the node’s key.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Here the parentheses are meant to signify that the expression is not
::
- [key_n value_n left right] value key [Tree-add] T
- -------------------------------------------------------
- [key_n value_n left (Tree-add key value right)]
+ [key_n value_n left right] value key [Tree-add] T
+ -------------------------------------------------------
+ [key_n value_n left (Tree-add key value right)]
-So how do we do this? We're going to want to use ``infra`` on some
+So how do we do this? 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 ``Tree-add`` to apply somehow. Considering the node as a
stack:
::
- right left value_n key_n value key [Tree-add] K
- -----------------------------------------------------
- right value key Tree-add left value_n key_n
+ right left value_n key_n value key [Tree-add] K
+ -----------------------------------------------------
+ right value key Tree-add left value_n key_n
Pretty easy:
::
- right left value_n key_n value key [Tree-add] cons cons dipdd
- right left value_n key_n [value key Tree-add] dipdd
- right value key Tree-add left value_n key_n
+ right left value_n key_n value key [Tree-add] cons cons dipdd
+ right left value_n key_n [value key Tree-add] dipdd
+ right value key Tree-add left value_n key_n
So:
::
- K == cons cons dipdd
+ K == cons cons dipdd
Looking at it from the point-of-view of the node as node again:
::
- [key_n value_n left right] [value key [Tree-add] K] infra
+ [key_n value_n left right] [value key [Tree-add] K] infra
Expand ``K`` and evaluate a little:
::
- [key_n value_n left right] [value key [Tree-add] K] infra
- [key_n value_n left right] [value key [Tree-add] cons cons dipdd] infra
- [key_n value_n left right] [[value key Tree-add] dipdd] infra
+ [key_n value_n left right] [value key [Tree-add] K] infra
+ [key_n value_n left right] [value key [Tree-add] cons cons dipdd] infra
+ [key_n value_n left right] [[value key Tree-add] dipdd] infra
Then, working backwards:
::
- [key_n value_n left right] [[value key Tree-add] dipdd] infra
- [key_n value_n left right] [value key Tree-add] [dipdd] cons infra
- [key_n value_n left right] value key [Tree-add] cons cons [dipdd] cons infra
+ [key_n value_n left right] [[value key Tree-add] dipdd] infra
+ [key_n value_n left right] [value key Tree-add] [dipdd] cons infra
+ [key_n value_n left right] value key [Tree-add] cons cons [dipdd] cons infra
And so ``T`` is just:
::
- T == cons cons [dipdd] cons infra
+ T == cons cons [dipdd] cons infra
.. code:: ipython2
['old_k' 'old_value' 'left' 'Tree-add' 'new_key' 'new_value' 'right']
-If the key we're adding is less than the node's key.
+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 [Tree-add] E
- [key_n value_n left right] value key [Tree-add] [P <] [Te] [Ee] ifte
+ [key_n value_n left right] value key [Tree-add] E
+ [key_n value_n left right] value key [Tree-add] [P <] [Te] [Ee] ifte
.. code:: ipython2
::
- Te == cons cons [dipd] cons infra
+ Te == cons cons [dipd] cons infra
.. code:: ipython2
::
- [key old_value left right] new_value key [Tree-add] Ee
- ------------------------------------------------------------
- [key new_value left right]
+ [key old_value left right] new_value key [Tree-add] Ee
+ ------------------------------------------------------------
+ [key new_value left right]
This is another easy one:
::
- Ee == pop swap roll< rest rest cons cons
+ Ee == pop swap roll< rest rest cons cons
Example:
::
- [key old_value left right] new_value key [Tree-add] pop swap roll< rest rest cons cons
- [key old_value left right] new_value key swap roll< rest rest cons cons
- [key old_value left right] key new_value roll< rest rest cons cons
- key new_value [key old_value left right] rest rest cons cons
- key new_value [ left right] cons cons
- [key new_value left right]
+ [key old_value left right] new_value key [Tree-add] pop swap roll< rest rest cons cons
+ [key old_value left right] new_value key swap roll< rest rest cons cons
+ [key old_value left right] key new_value roll< rest rest cons cons
+ key new_value [key old_value left right] rest rest cons cons
+ key new_value [ left right] cons cons
+ [key new_value left right]
.. code:: ipython2
::
- Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec
+ Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec
Putting it all together:
::
- Tree-new == swap [[] []] cons cons
- P == pop roll> pop first
- T == cons cons [dipdd] cons infra
- Te == cons cons [dipd] cons infra
- Ee == pop swap roll< rest rest cons cons
- E == [P <] [Te] [Ee] ifte
- R == [P >] [T] [E] ifte
+ Tree-new == swap [[] []] cons cons
+ P == pop roll> pop first
+ T == cons cons [dipdd] cons infra
+ Te == cons cons [dipd] cons infra
+ Ee == pop swap roll< rest rest cons cons
+ E == [P <] [Te] [Ee] ifte
+ R == [P >] [T] [E] ifte
- Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
+ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
.. code:: ipython2
Interlude: ``cmp`` combinator
-----------------------------
-Instead of mucking about with nested ``ifte`` combinators let's use
+Instead of mucking about with nested ``ifte`` combinators let’s use
``cmp`` which takes two values and three quoted programs on the stack
and runs one of the three depending on the results of comparing the two
values:
::
- a b [G] [E] [L] cmp
- ------------------------- a > b
- G
+ 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
+ E
- a b [G] [E] [L] cmp
- ------------------------- a < b
- L
+ a b [G] [E] [L] cmp
+ ------------------------- a < b
+ L
.. code:: ipython2
::
- [node_key node_value left right] value key [Tree-add] P
- ------------------------------------------------------------------------
- [node_key node_value left right] value key [Tree-add] key node_key
+ [node_key node_value left right] value key [Tree-add] P
+ ------------------------------------------------------------------------
+ [node_key node_value left right] value key [Tree-add] key node_key
-Let's start with ``over`` to get a copy of the key and then apply some
+Let’s start with ``over`` to get a copy of the key and then apply some
function ``Q`` with the ``nullary`` combinator so it can dig out the
node key (by throwing everything else away):
::
- P == over [Q] nullary
+ P == over [Q] nullary
- [node_key node_value left right] value key [Tree-add] over [Q] nullary
- [node_key node_value left right] value key [Tree-add] key [Q] nullary
+ [node_key node_value left right] value key [Tree-add] over [Q] nullary
+ [node_key node_value left right] value key [Tree-add] key [Q] nullary
And ``Q`` would be:
::
- Q == popop popop first
+ Q == popop popop first
- [node_key node_value left right] value key [Tree-add] key Q
- [node_key node_value left right] value key [Tree-add] key popop popop first
- [node_key node_value left right] value key popop first
- [node_key node_value left right] first
- node_key
+ [node_key node_value left right] value key [Tree-add] key Q
+ [node_key node_value left right] value key [Tree-add] key popop popop first
+ [node_key node_value left right] value key popop first
+ [node_key node_value left right] first
+ node_key
Or just:
::
- P == over [popop popop first] nullary
+ P == over [popop popop first] nullary
.. code:: ipython2
::
- [node_key node_value left right] value key [Tree-add] R1
- [node_key node_value left right] value key [Tree-add] P [T] [E] [Te] cmp
+ [node_key node_value left right] value key [Tree-add] R1
+ [node_key node_value left right] value key [Tree-add] P [T] [E] [Te] cmp
The line above becomes one of the three lines below:
::
- [node_key node_value left right] value key [Tree-add] T
- [node_key node_value left right] value key [Tree-add] E
- [node_key node_value left right] value key [Tree-add] Te
+ [node_key node_value left right] value key [Tree-add] T
+ [node_key node_value left right] value key [Tree-add] E
+ [node_key node_value left right] value key [Tree-add] Te
The definition is a little longer but, I think, more elegant and easier
to understand:
::
- Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec
+ Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec
.. code:: ipython2
A Function to Traverse this Structure
-------------------------------------
-Let's take a crack at writing a function that can recursively iterate or
+Let’s take a crack at writing a function that can recursively iterate or
traverse these trees.
Base case ``[]``
::
- Tree-iter == [not] [E] [R0] [R1] genrec
+ Tree-iter == [not] [E] [R0] [R1] genrec
-And since there's nothing at this node, we just ``pop`` it:
+And since there’s nothing at this node, we just ``pop`` it:
::
- Tree-iter == [not] [pop] [R0] [R1] genrec
+ Tree-iter == [not] [pop] [R0] [R1] genrec
Node case ``[key value left right]``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- Tree-iter == [not] [pop] [R0] [R1] genrec
- == [not] [pop] [R0 [Tree-iter] R1] ifte
+ Tree-iter == [not] [pop] [R0] [R1] genrec
+ == [not] [pop] [R0 [Tree-iter] R1] ifte
-Let's look at it *in situ*:
+Let’s look at it *in situ*:
::
- [key value left right] R0 [Tree-iter] R1
+ [key value left right] R0 [Tree-iter] R1
Processing the current node.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [key value left right] [F] dupdip [Tree-iter] R1
- [key value left right] F [key value left right] [Tree-iter] R1
+ [key value left right] [F] dupdip [Tree-iter] R1
+ [key value left right] F [key value left right] [Tree-iter] R1
-For example, if we're getting all the keys ``F`` would be ``first``:
+For example, if we’re getting all the keys ``F`` would be ``first``:
::
- R0 == [first] dupdip
+ R0 == [first] dupdip
- [key value left right] [first] dupdip [Tree-iter] R1
- [key value left right] first [key value left right] [Tree-iter] R1
- key [key value left right] [Tree-iter] R1
+ [key value left right] [first] dupdip [Tree-iter] R1
+ [key value left right] first [key value left right] [Tree-iter] R1
+ key [key value left right] [Tree-iter] R1
Recur
^^^^^
::
- key [key value left right] [Tree-iter] R1
- key [key value left right] [Tree-iter] [rest rest] dip
- key [key value left right] rest rest [Tree-iter]
- key [left right] [Tree-iter]
+ key [key value left right] [Tree-iter] R1
+ key [key value left right] [Tree-iter] [rest rest] dip
+ key [key value left right] rest rest [Tree-iter]
+ key [left right] [Tree-iter]
Hmm, will ``step`` do?
::
- key [left right] [Tree-iter] step
- key left Tree-iter [right] [Tree-iter] step
- key left-keys [right] [Tree-iter] step
- key left-keys right Tree-iter
- key left-keys right-keys
+ key [left right] [Tree-iter] step
+ key left Tree-iter [right] [Tree-iter] step
+ key left-keys [right] [Tree-iter] step
+ key left-keys right Tree-iter
+ key left-keys right-keys
Neat. So:
::
- R1 == [rest rest] dip step
+ R1 == [rest rest] dip step
Putting it together
~~~~~~~~~~~~~~~~~~~
::
- Tree-iter == [not] [pop] [[F] dupdip] [[rest rest] dip step] genrec
+ Tree-iter == [not] [pop] [[F] dupdip] [[rest rest] dip step] genrec
When I was reading this over I realized ``rest rest`` could go in
``R0``:
::
- Tree-iter == [not] [pop] [[F] dupdip rest rest] [step] genrec
+ Tree-iter == [not] [pop] [[F] dupdip rest rest] [step] genrec
(And ``[step] genrec`` is such a cool and suggestive combinator!)
::
- [F] Tree-iter
- ------------------------------------------------------
- [not] [pop] [[F] dupdip rest rest] [step] genrec
+ [F] Tree-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
+ [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
``Tree-iter``
~~~~~~~~~~~~~
::
- Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec
+ Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec
.. code:: ipython2
-----------------------------------
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 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.
::
- Tree-iter-order == [not] [pop] [R0] [R1] genrec
+ Tree-iter-order == [not] [pop] [R0] [R1] genrec
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
+ [key value left right] R0 [BTree-iter-order] R1
Process the left child.
~~~~~~~~~~~~~~~~~~~~~~~
::
- [key value left right] R0 [Tree-iter-order] R1
- [key value left right] dup third [Tree-iter-order] R1
- [key value left right] left [Tree-iter-order] R1
+ [key value left right] R0 [Tree-iter-order] R1
+ [key value left right] dup third [Tree-iter-order] R1
+ [key value left right] left [Tree-iter-order] R1
Now maybe:
::
- [key value left right] left [Tree-iter-order] [cons dip] dupdip
- [key value left right] left [Tree-iter-order] cons dip [Tree-iter-order]
- [key value left right] [left Tree-iter-order] dip [Tree-iter-order]
- left Tree-iter-order [key value left right] [Tree-iter-order]
+ [key value left right] left [Tree-iter-order] [cons dip] dupdip
+ [key value left right] left [Tree-iter-order] cons dip [Tree-iter-order]
+ [key value left right] [left Tree-iter-order] dip [Tree-iter-order]
+ left Tree-iter-order [key value left right] [Tree-iter-order]
Process the current node.
~~~~~~~~~~~~~~~~~~~~~~~~~
-So far, so good. Now we need to process the current node's values:
+So far, so good. Now we need to process the current node’s values:
::
- left Tree-iter-order [key value left right] [Tree-iter-order] [[F] dupdip] dip
- left Tree-iter-order [key value left right] [F] dupdip [Tree-iter-order]
- left Tree-iter-order [key value left right] F [key value left right] [Tree-iter-order]
+ left Tree-iter-order [key value left right] [Tree-iter-order] [[F] dupdip] dip
+ left Tree-iter-order [key value left right] [F] dupdip [Tree-iter-order]
+ left Tree-iter-order [key value left right] F [key value left right] [Tree-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.
+``cons``\ ’d them before beginning maybe? For functions like ``first``
+it works fine as-is.
::
- left Tree-iter-order [key value left right] first [key value left right] [Tree-iter-order]
- left Tree-iter-order key [key value left right] [Tree-iter-order]
+ left Tree-iter-order [key value left right] first [key value left right] [Tree-iter-order]
+ left Tree-iter-order key [key value left right] [Tree-iter-order]
Process the right child.
~~~~~~~~~~~~~~~~~~~~~~~~
::
- left Tree-iter-order key [key value left right] [Tree-iter-order] [rest rest rest first] dip
- left Tree-iter-order key right [Tree-iter-order]
+ left Tree-iter-order key [key value left right] [Tree-iter-order] [rest rest rest first] dip
+ left Tree-iter-order key right [Tree-iter-order]
Then, of course, we just need ``i`` to run ``Tree-iter-order`` on the
right side:
::
- left Tree-iter-order key right [Tree-iter-order] i
- left Tree-iter-order key right Tree-iter-order
+ left Tree-iter-order key right [Tree-iter-order] i
+ left Tree-iter-order key right Tree-iter-order
Defining ``Tree-iter-order``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- R1 == [cons dip] dupdip [[F] dupdip] dip [rest rest rest first] dip i
+ R1 == [cons dip] dupdip [[F] dupdip] dip [rest rest rest first] dip i
-Let's do a little semantic factoring:
+Let’s do a little semantic factoring:
::
- fourth == rest rest rest first
+ fourth == rest rest rest first
- proc_left == [cons dip] dupdip
- proc_current == [[F] dupdip] dip
- proc_right == [fourth] dip i
+ proc_left == [cons dip] dupdip
+ proc_current == [[F] dupdip] dip
+ proc_right == [fourth] dip i
- Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] genrec
+ Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] genrec
Now we can sort sequences.
Getting values by key
---------------------
-Let's derive a function that accepts a tree and a key and returns the
+Let’s derive a function that accepts a tree and a key and returns the
value associated with that key.
::
- tree key Tree-get
- -----------------------
- value
+ tree key Tree-get
+ -----------------------
+ value
-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", I think.)
+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”, I think.)
-Let's pass the buck to the caller by making the base case a given, you
+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] Tree-get
- ---------------------------- key in tree
- value
+ tree key [E] Tree-get
+ ---------------------------- key in tree
+ value
- tree key [E] Tree-get
- ---------------------------- key not in tree
- [] key E
+ tree key [E] Tree-get
+ ---------------------------- key not in tree
+ [] key E
The base case ``[]``
~~~~~~~~~~~~~~~~~~~~
::
- Tree-get == [pop not] [E] [R0] [R1] genrec
+ Tree-get == [pop not] [E] [R0] [R1] genrec
So we define:
::
- Tree-get == [pop not] swap [R0] [R1] genrec
+ Tree-get == [pop not] swap [R0] [R1] genrec
Note that this ``Tree-get`` creates a slightly different function than
itself and *that function* does the actual recursion. This kind of
::
- tree key [E] [pop not] swap [R0] [R1] genrec
- tree key [pop not] [E] [R0] [R1] genrec
+ 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
+ [pop not] [E] [R0] [R1] genrec
Node case ``[key value left right]``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- [key value left right] key R0 [BTree-get] 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, otherwise recur on one of the child
-nodes. So it's very similar to the above funtion, with ``[R0] == []``
+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
+ [key value left right] key [BTree-get] P [T>] [E] [T<] cmp
Predicate
^^^^^^^^^
::
- P == over [get-node-key] nullary
- get-node-key == pop popop first
+ P == over [get-node-key] nullary
+ get-node-key == pop popop first
The only difference is that ``get-node-key`` does one less ``pop``
-because there's no value to discard.
+because there’s no value to discard.
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<
+ [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<
Greater than and less than
^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [key_n value_n left right] key [BTree-get] T>
- ---------------------------------------------------
- right key BTree-get
+ [key_n value_n left right] key [BTree-get] T>
+ ---------------------------------------------------
+ right key BTree-get
And:
::
- [key_n value_n left right] key [BTree-get] T<
- ---------------------------------------------------
- left 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
+ 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
+ [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
Equal keys
^^^^^^^^^^
-Return the node's value:
+Return the node’s value:
::
- [key_n value_n left right] key [BTree-get] E == value_n
+ [key_n value_n left right] key [BTree-get] E == value_n
- E == popop second
+ E == popop second
``Tree-get``
~~~~~~~~~~~~
::
- 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
+ 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
- Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
+ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
.. code:: ipython2
Tree-delete
-----------
-Now let's write a function that can return a tree datastructure with a
+Now let’s write a function that can return a tree datastructure with a
key, value pair deleted:
::
- tree key Tree-delete
- ---------------------------
- tree
+ tree key Tree-delete
+ ---------------------------
+ tree
If the key is not in tree it just returns the tree unchanged.
::
- Tree-Delete == [pop not] [pop] [R0] [R1] genrec
+ Tree-Delete == [pop not] [pop] [R0] [R1] genrec
Recur
~~~~~
-Now we get to figure out the recursive case. We need the node's key to
+Now we get to figure out the recursive case. We need the node’s key to
compare and we need to carry the key into recursive branches. Let ``D``
be shorthand for ``Tree-Delete``:
::
- D == Tree-Delete == [pop not] [pop] [R0] [R1] genrec
+ D == Tree-Delete == [pop not] [pop] [R0] [R1] genrec
- [node_key node_value left right] key R0 [D] R1
- [node_key node_value left right] key over first swap dup [D] cons R1′
- [node_key node_value left right] key [...] first swap dup [D] cons R1′
- [node_key node_value left right] key node_key swap dup [D] cons R1′
- [node_key node_value left right] node_key key dup [D] cons R1′
- [node_key node_value left right] node_key key key [D] cons R1′
- [node_key node_value left right] node_key key [key D] R1′
+ [node_key node_value left right] key R0 [D] R1
+ [node_key node_value left right] key over first swap dup [D] cons R1′
+ [node_key node_value left right] key [...] first swap dup [D] cons R1′
+ [node_key node_value left right] key node_key swap dup [D] cons R1′
+ [node_key node_value left right] node_key key dup [D] cons R1′
+ [node_key node_value left right] node_key key key [D] cons R1′
+ [node_key node_value left right] node_key key [key D] R1′
And then:
::
- [node_key node_value left right] node_key key [key D] R1′
- [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
- [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
- [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
+ [node_key node_value left right] node_key key [key D] R1′
+ [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
+ [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
+ [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
So:
::
- R0 == over first swap dup
- R1 == cons roll> [T>] [E] [T<] cmp
+ R0 == over first swap dup
+ R1 == cons roll> [T>] [E] [T<] cmp
Compare Keys
~~~~~~~~~~~~
::
- [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
+ [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
Then becomes one of these three:
::
- [node_key node_value left right] [key D] T>
- [node_key node_value left right] [key D] E
- [node_key node_value left right] [key D] T<
+ [node_key node_value left right] [key D] T>
+ [node_key node_value left right] [key D] E
+ [node_key node_value left right] [key D] T<
Greater than case and less than case
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- [node_key node_value left right] [F] T>
- -------------------------------------------------
- [node_key node_value (left F) right]
+ [node_key node_value left right] [F] T>
+ -------------------------------------------------
+ [node_key node_value (left F) right]
- [node_key node_value left right] [F] T<
- -------------------------------------------------
- [node_key node_value left (right F)]
+ [node_key node_value left right] [F] T<
+ -------------------------------------------------
+ [node_key node_value left (right F)]
First, treating the node as a stack:
::
- right left node_value node_key [key D] dipd
- right left key D node_value node_key
- right left' node_value node_key
+ right left node_value node_key [key D] dipd
+ right left key D node_value node_key
+ right left' node_value node_key
Ergo:
::
- [node_key node_value left right] [key D] [dipd] cons infra
+ [node_key node_value left right] [key D] [dipd] cons infra
So:
::
- T> == [dipd] cons infra
- T< == [dipdd] cons infra
+ T> == [dipd] cons infra
+ T< == [dipdd] cons infra
The else case
~~~~~~~~~~~~~
::
- [node_key node_value left right] [key D] E
- ------------------------------------------------
- tree
+ [node_key node_value left right] [key D] E
+ ------------------------------------------------
+ tree
-We have to handle three cases, so let's use ``cond``.
+We have to handle three cases, so let’s use ``cond``.
One or more child nodes are ``[]``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [default]
- ] cond
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [default]
+ ] cond
Both child nodes are non-empty.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- default == [E′] cons infra
+ default == [E′] cons infra
- [node_key node_value left right] [key D] default
- [node_key node_value left right] [key D] [E′] cons infra
- [node_key node_value left right] [[key D] E′] infra
+ [node_key node_value left right] [key D] default
+ [node_key node_value left right] [key D] [E′] cons infra
+ [node_key node_value left right] [[key D] E′] infra
- right left node_value node_key [key D] E′
+ right left node_value node_key [key D] E′
-First things first, we no longer need this node's key and value:
+First things first, we no longer need this node’s key and value:
::
- right left node_value node_key [key D] roll> popop E″
- right left [key D] node_value node_key popop E″
- right left [key D] E″
+ right left node_value node_key [key D] roll> popop E″
+ right left [key D] node_value node_key popop E″
+ right left [key D] E″
We have to we find the highest (right-most) node in our lower (left) sub-tree:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- right left [key D] E″
+ right left [key D] E″
Ditch the key:
::
- right left [key D] rest E‴
- right left [D] E‴
+ right left [key D] rest E‴
+ right left [D] E‴
Find the right-most node:
::
- right left [D] [dup W] dip E⁗
- right left dup W [D] E⁗
- right left left W [D] E⁗
+ right left [D] [dup W] dip E⁗
+ right left dup W [D] E⁗
+ right left left W [D] E⁗
Consider:
::
- left W
+ left W
We know left is not empty:
::
- [L_key L_value L_left L_right] W
+ [L_key L_value L_left L_right] W
We want to keep extracting the right node as long as it is not empty:
::
- W.rightmost == [P] [B] while
+ W.rightmost == [P] [B] while
- left W.rightmost W′
+ left W.rightmost W′
The predicate:
::
- [L_key L_value L_left L_right] P
- [L_key L_value L_left L_right] fourth
- L_right
+ [L_key L_value L_left L_right] P
+ [L_key L_value L_left L_right] fourth
+ L_right
This can run on ``[]`` so must be guarded:
::
- ?fourth == [] [fourth] [] ifte
+ ?fourth == [] [fourth] [] ifte
-( if\_not\_empty == [] swap [] ifte ?fourth == [fourth] if\_not\_empty )
+( if_not_empty == [] swap [] ifte ?fourth == [fourth] if_not_empty )
The body is just ``fourth``:
::
- left [?fourth] [fourth] while W′
- rightest W′
+ left [?fourth] [fourth] while W′
+ rightest W′
So:
::
- W.rightmost == [?fourth] [fourth] while
+ W.rightmost == [?fourth] [fourth] while
Found right-most node in our left sub-tree
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [R_key R_value R_left R_right] W′
- [R_key R_value R_left R_right] W′
- [R_key R_value R_left R_right] uncons uncons pop
- R_key [R_value R_left R_right] uncons pop
- R_key R_value [R_left R_right] pop
- R_key R_value
+ [R_key R_value R_left R_right] W′
+ [R_key R_value R_left R_right] W′
+ [R_key R_value R_left R_right] uncons uncons pop
+ R_key [R_value R_left R_right] uncons pop
+ R_key R_value [R_left R_right] pop
+ R_key R_value
So:
::
- W == [?fourth] [fourth] while uncons uncons pop
+ W == [?fourth] [fourth] while uncons uncons pop
And:
::
- right left left W [D] E⁗
- right left R_key R_value [D] E⁗
+ right left left W [D] E⁗
+ right left R_key R_value [D] E⁗
Replace current node key and value, recursively delete rightmost
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- right left [R_key D] i R_value R_key
- right left R_key D R_value R_key
- right left′ R_value R_key
+ right left [R_key D] i R_value R_key
+ right left R_key D R_value R_key
+ right left′ R_value R_key
If we adjust our definition of ``W`` to include ``over`` at the end:
::
- W == [fourth] [fourth] while uncons uncons pop over
+ W == [fourth] [fourth] while uncons uncons pop over
That will give us:
::
- right left R_key R_value R_key [D] E⁗
+ right left R_key R_value R_key [D] E⁗
- right left R_key R_value R_key [D] cons dipd E⁗′
- right left R_key R_value [R_key D] dipd E⁗′
- right left R_key D R_key R_value E⁗′
- right left′ R_key R_value E⁗′
- right left′ R_key R_value swap
- right left′ R_value R_key
+ right left R_key R_value R_key [D] cons dipd E⁗′
+ right left R_key R_value [R_key D] dipd E⁗′
+ right left R_key D R_key R_value E⁗′
+ right left′ R_key R_value E⁗′
+ right left′ R_key R_value swap
+ right left′ R_value R_key
So:
::
- E′ == roll> popop E″
+ E′ == roll> popop E″
- E″ == rest E‴
+ E″ == rest E‴
- E‴ == [dup W] dip E⁗
+ E‴ == [dup W] dip E⁗
- E⁗ == cons dipdd swap
+ E⁗ == cons dipdd swap
Substituting:
::
- W == [fourth] [fourth] while uncons uncons pop over
- E′ == roll> popop rest [dup W] dip cons dipd swap
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [[E′] cons infra]
- ] cond
+ W == [fourth] [fourth] while uncons uncons pop over
+ E′ == roll> popop rest [dup W] dip cons dipd swap
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [[E′] cons infra]
+ ] cond
Minor rearrangement, move ``dup`` into ``W``:
::
- W == dup [fourth] [fourth] while uncons uncons pop over
- E′ == roll> popop rest [W] dip cons dipd swap
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [[E′] cons infra]
- ] cond
+ W == dup [fourth] [fourth] while uncons uncons pop over
+ E′ == roll> popop rest [W] dip cons dipd swap
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [[E′] cons infra]
+ ] cond
Refactoring
~~~~~~~~~~~
::
- W.rightmost == [fourth] [fourth] while
- W.unpack == uncons uncons pop
- W == dup W.rightmost W.unpack over
- E.clear_stuff == roll> popop rest
- E.delete == cons dipd
- E.0 == E.clear_stuff [W] dip E.delete swap
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [[E.0] cons infra]
- ] cond
- T> == [dipd] cons infra
- T< == [dipdd] cons infra
- R0 == over first swap dup
- R1 == cons roll> [T>] [E] [T<] cmp
- BTree-Delete == [pop not] swap [R0] [R1] genrec
-
-By the standards of the code I've written so far, this is a *huge* Joy
+ W.rightmost == [fourth] [fourth] while
+ W.unpack == uncons uncons pop
+ W == dup W.rightmost W.unpack over
+ E.clear_stuff == roll> popop rest
+ E.delete == cons dipd
+ E.0 == E.clear_stuff [W] dip E.delete swap
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [[E.0] cons infra]
+ ] cond
+ T> == [dipd] cons infra
+ T< == [dipdd] cons infra
+ R0 == over first swap dup
+ R1 == cons roll> [T>] [E] [T<] cmp
+ BTree-Delete == [pop not] swap [R0] [R1] genrec
+
+By the standards of the code I’ve written so far, this is a *huge* Joy
program.
.. code:: ipython2
::
- fourth == rest_two rest first
- ?fourth == [] [fourth] [] ifte
- first_two == uncons uncons pop
- ccons == cons cons
- cinf == cons infra
- rest_two == rest rest
-
- _Tree_T> == [dipd] cinf
- _Tree_T< == [dipdd] cinf
-
- _Tree_add_P == over [popop popop first] nullary
- _Tree_add_T> == ccons _Tree_T<
- _Tree_add_T< == ccons _Tree_T>
- _Tree_add_Ee == pop swap roll< rest_two ccons
- _Tree_add_R == _Tree_add_P [_Tree_add_T>] [_Tree_add_Ee] [_Tree_add_T<] cmp
- _Tree_add_E == [pop] dipd Tree-new
-
- _Tree_iter_order_left == [cons dip] dupdip
- _Tree_iter_order_current == [[F] dupdip] dip
- _Tree_iter_order_right == [fourth] dip i
- _Tree_iter_order_R == _Tree_iter_order_left _Tree_iter_order_current _Tree_iter_order_right
-
- _Tree_get_P == over [pop popop first] nullary
- _Tree_get_T> == [fourth] dipd i
- _Tree_get_T< == [third] dipd i
- _Tree_get_E == popop second
- _Tree_get_R == _Tree_get_P [_Tree_get_T>] [_Tree_get_E] [_Tree_get_T<] cmp
-
- _Tree_delete_rightmost == [?fourth] [fourth] while
- _Tree_delete_clear_stuff == roll> popop rest
- _Tree_delete_del == dip cons dipd swap
- _Tree_delete_W == dup _Tree_delete_rightmost first_two over
- _Tree_delete_E.0 == _Tree_delete_clear_stuff [_Tree_delete_W] _Tree_delete_del
- _Tree_delete_E == [[[pop third not] pop fourth] [[pop fourth not] pop third] [[_Tree_delete_E.0] cinf]] cond
- _Tree_delete_R0 == over first swap dup
- _Tree_delete_R1 == cons roll> [_Tree_T>] [_Tree_delete_E] [_Tree_T<] cmp
-
- Tree-new == swap [[] []] ccons
- Tree-add == [popop not] [_Tree_add_E] [] [_Tree_add_R] genrec
- Tree-iter == [not] [pop] roll< [dupdip rest_two] cons [step] genrec
- Tree-iter-order == [not] [pop] [dup third] [_Tree_iter_order_R] genrec
- Tree-get == [pop not] swap [] [_Tree_get_R] genrec
- Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec
+ fourth == rest_two rest first
+ ?fourth == [] [fourth] [] ifte
+ first_two == uncons uncons pop
+ ccons == cons cons
+ cinf == cons infra
+ rest_two == rest rest
+
+ _Tree_T> == [dipd] cinf
+ _Tree_T< == [dipdd] cinf
+
+ _Tree_add_P == over [popop popop first] nullary
+ _Tree_add_T> == ccons _Tree_T<
+ _Tree_add_T< == ccons _Tree_T>
+ _Tree_add_Ee == pop swap roll< rest_two ccons
+ _Tree_add_R == _Tree_add_P [_Tree_add_T>] [_Tree_add_Ee] [_Tree_add_T<] cmp
+ _Tree_add_E == [pop] dipd Tree-new
+
+ _Tree_iter_order_left == [cons dip] dupdip
+ _Tree_iter_order_current == [[F] dupdip] dip
+ _Tree_iter_order_right == [fourth] dip i
+ _Tree_iter_order_R == _Tree_iter_order_left _Tree_iter_order_current _Tree_iter_order_right
+
+ _Tree_get_P == over [pop popop first] nullary
+ _Tree_get_T> == [fourth] dipd i
+ _Tree_get_T< == [third] dipd i
+ _Tree_get_E == popop second
+ _Tree_get_R == _Tree_get_P [_Tree_get_T>] [_Tree_get_E] [_Tree_get_T<] cmp
+
+ _Tree_delete_rightmost == [?fourth] [fourth] while
+ _Tree_delete_clear_stuff == roll> popop rest
+ _Tree_delete_del == dip cons dipd swap
+ _Tree_delete_W == dup _Tree_delete_rightmost first_two over
+ _Tree_delete_E.0 == _Tree_delete_clear_stuff [_Tree_delete_W] _Tree_delete_del
+ _Tree_delete_E == [[[pop third not] pop fourth] [[pop fourth not] pop third] [[_Tree_delete_E.0] cinf]] cond
+ _Tree_delete_R0 == over first swap dup
+ _Tree_delete_R1 == cons roll> [_Tree_T>] [_Tree_delete_E] [_Tree_T<] cmp
+
+ Tree-new == swap [[] []] ccons
+ Tree-add == [popop not] [_Tree_add_E] [] [_Tree_add_R] genrec
+ Tree-iter == [not] [pop] roll< [dupdip rest_two] cons [step] genrec
+ Tree-iter-order == [not] [pop] [dup third] [_Tree_iter_order_R] genrec
+ Tree-get == [pop not] swap [] [_Tree_get_R] genrec
+ Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec
::
- -b ± sqrt(b^2 - 4 * a * c)
- --------------------------------
- 2 * a
+ -b ± sqrt(b^2 - 4 * a * c)
+ --------------------------------
+ 2 * a
:math:`\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}`
::
- b neg
+ b neg
``sqrt(b^2 - 4 * a * c)``
~~~~~~~~~~~~~~~~~~~~~~~~~
::
- b sqr 4 a c * * - sqrt
+ b sqr 4 a c * * - sqrt
``/2a``
~~~~~~~
::
- a 2 * /
+ a 2 * /
``±``
~~~~~
::
- pm == [+] [-] cleave popdd
+ pm == [+] [-] cleave popdd
Putting Them Together
~~~~~~~~~~~~~~~~~~~~~
::
- b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
+ b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
We use ``app2`` to compute both roots by using a quoted program
``[2a /]`` built with ``cons``.
::
- b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
- b [neg] dupdip sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
- b a c [[neg] dupdip sqr 4] dipd * * - sqrt pm a 2 * [/] cons app2
- b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
- b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
+ b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
+ b [neg] dupdip sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
+ b a c [[neg] dupdip sqr 4] dipd * * - sqrt pm a 2 * [/] cons app2
+ b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
+ b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
-The three arguments are to the left, so we can "chop off" everything to
-the right and say it's the definition of the ``quadratic`` function:
+The three arguments are to the left, so we can “chop off” everything to
+the right and say it’s the definition of the ``quadratic`` function:
.. code:: ipython2
define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
-Let's try it out:
+Let’s try it out:
.. code:: ipython2
::
- [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."
+ [if] [then] [rec1] [rec2] genrec
+ ---------------------------------------------------------------------
+ [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
+
+From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun:
+
+ “The genrec combinator takes four program parameters in addition to
+ whatever data parameters it needs. Fourth from the top is an if-part,
+ followed by a then-part. If the if-part yields true, then the
+ then-part is executed and the combinator terminates. The other two
+ parameters are the rec1-part and the rec2-part. If the if-part yields
+ false, the rec1-part is executed. Following that the four program
+ parameters and the combinator are again pushed onto the stack bundled
+ up in a quoted form. Then the rec2-part is executed, where it will
+ find the bundled form. Typically it will then execute the bundled
+ form, either with i or with app2, or some other combinator.”
Designing Recursive Functions
-----------------------------
The way to design one of these is to fix your base case and test and
-then treat ``R1`` and ``R2`` as an else-part "sandwiching" a quotation
+then treat ``R1`` and ``R2`` as an else-part “sandwiching” a quotation
of the whole function.
For example, given a (general recursive) function ``F``:
::
- F == [I] [T] [R1] [R2] genrec
- == [I] [T] [R1 [F] R2] ifte
+ F == [I] [T] [R1] [R2] genrec
+ == [I] [T] [R1 [F] R2] ifte
If the ``[I]`` predicate is false you must derive ``R1`` and ``R2``
from:
::
- ... R1 [F] R2
+ ... R1 [F] R2
Set the stack arguments in front and figure out what ``R1`` and ``R2``
have to do to apply the quoted ``[F]`` in the proper way.
::
- P == [I] [T] [R] primrec
- == [I] [T] [R [P] i] ifte
- == [I] [T] [R P] ifte
+ P == [I] [T] [R] primrec
+ == [I] [T] [R [P] i] ifte
+ == [I] [T] [R P] ifte
`Hylomorphism <https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29>`__
------------------------------------------------------------------------------------
- A combiner ``F :: (B, C) -> C``
- A predicate ``P :: A -> Bool`` to detect the base case
- A base case value ``c :: C``
-- Recursive calls (zero or more); it has a "call stack in the form of a
- cons list".
+- 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.
return H
-Cf. `"Bananas, Lenses, & Barbed
-Wire" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
+Cf. `“Bananas, Lenses, & Barbed
+Wire” <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
Note that during evaluation of ``H()`` the intermediate ``b`` values are
-stored in the Python call stack. This is what is meant by "call stack in
-the form of a cons list".
+stored in the Python call stack. This is what is meant by “call stack in
+the form of a cons list”.
Hylomorphism in Joy
-------------------
::
- H == [P] c [G] [F] hylomorphism
+ H == [P] c [G] [F] hylomorphism
The function ``H`` is recursive, so we start with ``ifte`` and set the
else-part to some function ``J`` that will contain a quoted copy of
::
- H == [P] [pop c] [J] ifte
+ 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.
+ 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
+ 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
+ H == [P] [pop c] [G [H] dip F] ifte
+ H == [P] [pop c] [G] [dip F] genrec
This is the form of a hylomorphism in Joy, which nicely illustrates that
it is a simple specialization of the general recursion combinator.
::
- H == [P] c [G] [F] hylomorphism == [P] [pop c] [G] [dip F] genrec
+ H == [P] c [G] [F] hylomorphism == [P] [pop c] [G] [dip F] genrec
Derivation of ``hylomorphism`` combinator
-----------------------------------------
::
- [P] c [G] [F] hylomorphism
- ------------------------------------------
- [P] [pop c] [G] [dip F] genrec
+ [P] c [G] [F] hylomorphism
+ ------------------------------------------
+ [P] [pop c] [G] [dip F] genrec
Working in reverse:
::
- 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
+ H == [P] [pop c] [G] [dip F] genrec
+ [P] [c] [pop] swoncat [G] [F] [dip] swoncat genrec
+ [P] c unit [pop] swoncat [G] [F] [dip] swoncat genrec
+ [P] c [G] [F] [unit [pop] swoncat] dipd [dip] swoncat genrec
At this point all of the arguments (givens) to the hylomorphism are to
the left so we have a definition for ``hylomorphism``:
::
- hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
+ hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
.. code:: ipython2
Example: Finding `Triangular Numbers <https://en.wikipedia.org/wiki/Triangular_number>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Let's write a function that, given a positive integer, returns the sum
+Let’s write a function that, given a positive integer, returns the sum
of all positive integers less than that one. (In this case the types
``A``, ``B`` and ``C`` are all ``int``.)
define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')
-Let's try it:
+Let’s try it:
.. code:: ipython2
There are at least four kinds of recursive combinator, depending on two
choices. The first choice is whether the combiner function ``F`` should
be evaluated during the recursion or pushed into the pending expression
-to be "collapsed" at the end. The second choice is whether the combiner
+to be “collapsed” at the end. The second choice is whether the combiner
needs to operate on the current value of the datastructure or the
-generator's output, in other words, whether ``F`` or ``G`` should run
+generator’s output, in other words, whether ``F`` or ``G`` should run
first in the recursive branch.
::
- H1 == [P] [pop c] [G ] [dip F] genrec
- H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
- H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
- H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
+ H1 == [P] [pop c] [G ] [dip F] genrec
+ H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
+ H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
+ H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
The working of the generator function ``G`` differs slightly for each.
Consider the recursive branches:
::
- ... a G [H1] dip F w/ a G == a′ b
+ ... a G [H1] dip F w/ a G == a′ b
- ... c a G [F] dip H2 a G == b a′
+ ... c a G [F] dip H2 a G == b a′
- ... a [G] dupdip [H3] dip F a G == a′
+ ... a [G] dupdip [H3] dip F a G == a′
- ... c a [F] dupdip G H4 a G == a′
+ ... c a [F] dupdip G H4 a G == a′
The following four sections illustrate how these work, omitting the
predicate evaluation.
::
- H1 == [P] [pop c] [G] [dip F] genrec
+ H1 == [P] [pop c] [G] [dip F] genrec
Iterate n times.
::
- ... a G [H1] dip F
- ... a′ b [H1] dip F
- ... a′ H1 b F
- ... a′ G [H1] dip F b F
- ... a″ b′ [H1] dip F b F
- ... a″ H1 b′ F b F
- ... a″ G [H1] dip F b′ F b F
- ... a‴ b″ [H1] dip F b′ F b F
- ... a‴ H1 b″ F b′ F b F
- ... a‴ pop c b″ F b′ F b F
- ... c b″ F b′ F b F
- ... d b′ F b F
- ... d′ b F
- ... d″
+ ... a G [H1] dip F
+ ... a′ b [H1] dip F
+ ... a′ H1 b F
+ ... a′ G [H1] dip F b F
+ ... a″ b′ [H1] dip F b F
+ ... a″ H1 b′ F b F
+ ... a″ G [H1] dip F b′ F b F
+ ... a‴ b″ [H1] dip F b′ F b F
+ ... a‴ H1 b″ F b′ F b F
+ ... a‴ pop c b″ F b′ F b F
+ ... c b″ F b′ F b F
+ ... d b′ F b F
+ ... d′ b F
+ ... d″
This form builds up a pending expression (continuation) that contains
the intermediate results along with the pending combiner functions. When
the base case is reached the last term is replaced by the identity value
-``c`` and the continuation "collapses" into the final result using the
+``c`` and the continuation “collapses” into the final result using the
combiner ``F``.
``H2``
::
- H2 == c swap [P] [pop] [G [F] dip] primrec
+ H2 == c swap [P] [pop] [G [F] dip] primrec
- ... c a G [F] dip H2
- ... c b a′ [F] dip H2
- ... c b F a′ H2
- ... d a′ H2
- ... d a′ G [F] dip H2
- ... d b′ a″ [F] dip H2
- ... d b′ F a″ H2
- ... d′ a″ H2
- ... d′ a″ G [F] dip H2
- ... d′ b″ a‴ [F] dip H2
- ... d′ b″ F a‴ H2
- ... d″ a‴ H2
- ... d″ a‴ pop
- ... d″
+ ... c a G [F] dip H2
+ ... c b a′ [F] dip H2
+ ... c b F a′ H2
+ ... d a′ H2
+ ... d a′ G [F] dip H2
+ ... d b′ a″ [F] dip H2
+ ... d b′ F a″ H2
+ ... d′ a″ H2
+ ... d′ a″ G [F] dip H2
+ ... d′ b″ a‴ [F] dip H2
+ ... d′ b″ F a‴ H2
+ ... d″ a‴ H2
+ ... d″ a‴ pop
+ ... d″
``H3``
~~~~~~
-If you examine the traces above you'll see that the combiner ``F`` only
-gets to operate on the results of ``G``, it never "sees" the first value
+If you examine the traces above you’ll see that the combiner ``F`` only
+gets to operate on the results of ``G``, it never “sees” the first value
``a``. If the combiner and the generator both need to work on the
current value then ``dup`` must be used, and the generator must produce
one item instead of two (the b is instead the duplicate of a.)
::
- H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
+ H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
- ... a [G] dupdip [H3] dip F
- ... a G a [H3] dip F
- ... a′ a [H3] dip F
- ... a′ H3 a F
- ... a′ [G] dupdip [H3] dip F a F
- ... a′ G a′ [H3] dip F a F
- ... a″ a′ [H3] dip F a F
- ... a″ H3 a′ F a F
- ... a″ [G] dupdip [H3] dip F a′ F a F
- ... a″ G a″ [H3] dip F a′ F a F
- ... a‴ a″ [H3] dip F a′ F a F
- ... a‴ H3 a″ F a′ F a F
- ... a‴ pop c a″ F a′ F a F
- ... c a″ F a′ F a F
- ... d a′ F a F
- ... d′ a F
- ... d″
+ ... a [G] dupdip [H3] dip F
+ ... a G a [H3] dip F
+ ... a′ a [H3] dip F
+ ... a′ H3 a F
+ ... a′ [G] dupdip [H3] dip F a F
+ ... a′ G a′ [H3] dip F a F
+ ... a″ a′ [H3] dip F a F
+ ... a″ H3 a′ F a F
+ ... a″ [G] dupdip [H3] dip F a′ F a F
+ ... a″ G a″ [H3] dip F a′ F a F
+ ... a‴ a″ [H3] dip F a′ F a F
+ ... a‴ H3 a″ F a′ F a F
+ ... a‴ pop c a″ F a′ F a F
+ ... c a″ F a′ F a F
+ ... d a′ F a F
+ ... d′ a F
+ ... d″
``H4``
~~~~~~
::
- H4 == c swap [P] [pop] [[F] dupdip G] primrec
+ H4 == c swap [P] [pop] [[F] dupdip G] primrec
- ... c a [F] dupdip G H4
- ... c a F a G H4
- ... d a G H4
- ... d a′ H4
- ... d a′ [F] dupdip G H4
- ... d a′ F a′ G H4
- ... d′ a′ G H4
- ... d′ a″ H4
- ... d′ a″ [F] dupdip G H4
- ... d′ a″ F a″ G H4
- ... d″ a″ G H4
- ... d″ a‴ H4
- ... d″ a‴ pop
- ... d″
+ ... c a [F] dupdip G H4
+ ... c a F a G H4
+ ... d a G H4
+ ... d a′ H4
+ ... d a′ [F] dupdip G H4
+ ... d a′ F a′ G H4
+ ... d′ a′ G H4
+ ... d′ a″ H4
+ ... d′ a″ [F] dupdip G H4
+ ... d′ a″ F a″ G H4
+ ... d″ a″ G H4
+ ... d″ a‴ H4
+ ... d″ a‴ pop
+ ... d″
Anamorphism
-----------
::
- A == [P] [] [G] [swons] hylomorphism
+ A == [P] [] [G] [swons] hylomorphism
-``range`` et. al.
-~~~~~~~~~~~~~~~~~
-
-An example of an anamorphism is the ``range`` function which generates
-the list of integers from 0 to *n* - 1 given *n*.
+``range`` et. al. An example of an anamorphism is the ``range`` function which generates the list of integers from 0 to *n* - 1 given *n*.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each of the above variations can be used to make four slightly different
``range`` functions.
::
- H1 == [P] [pop c] [G] [dip F] genrec
- == [0 <=] [pop []] [-- dup] [dip swons] genrec
+ H1 == [P] [pop c] [G] [dip F] genrec
+ == [0 <=] [pop []] [-- dup] [dip swons] genrec
.. code:: ipython2
::
- H2 == c swap [P] [pop] [G [F] dip] primrec
- == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
+ H2 == c swap [P] [pop] [G [F] dip] primrec
+ == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
.. code:: ipython2
::
- H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
- == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
+ H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
+ == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
.. code:: ipython2
::
- H4 == c swap [P] [pop] [[F] dupdip G ] primrec
- == [] swap [0 <=] [pop] [[swons] dupdip --] primrec
+ H4 == c swap [P] [pop] [[F] dupdip G ] primrec
+ == [] swap [0 <=] [pop] [[swons] dupdip --] primrec
.. code:: ipython2
::
- C == [not] c [uncons swap] [F] hylomorphism
+ C == [not] c [uncons swap] [F] hylomorphism
.. code:: ipython2
::
- sum == [not] 0 [swuncons] [+] hylomorphism
+ sum == [not] 0 [swuncons] [+] hylomorphism
.. code:: ipython2
::
- H4 == c swap [P] [pop] [[F] dupdip G] primrec
+ H4 == c swap [P] [pop] [[F] dupdip G] primrec
With:
::
- c == 1
- F == *
- G == --
- P == 1 <=
+ c == 1
+ F == *
+ G == --
+ P == 1 <=
.. code:: ipython2
Example: ``tails``
------------------
-An example of a paramorphism for lists given in the `"Bananas..."
+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.
+is ``tails`` which returns the list of “tails” of a list.
::
- [1 2 3] tails
- --------------------
- [[] [3] [2 3]]
+ [1 2 3] tails
+ --------------------
+ [[] [3] [2 3]]
We can build as we go, and we want ``F`` to run after ``G``, so we use
pattern ``H2``:
::
- H2 == c swap [P] [pop] [G [F] dip] primrec
+ H2 == c swap [P] [pop] [G [F] dip] primrec
We would use:
::
- c == []
- F == swons
- G == rest dup
- P == not
+ c == []
+ F == swons
+ G == rest dup
+ P == not
.. code:: ipython2
Conclusion: Patterns of Recursion
---------------------------------
-Our story so far...
+Our story so far…
Hylo-, Ana-, Cata-
~~~~~~~~~~~~~~~~~~
::
- H == [P ] [pop c ] [G ] [dip F ] genrec
- A == [P ] [pop []] [G ] [dip swap cons] genrec
- C == [not] [pop c ] [uncons swap] [dip F ] genrec
+ H == [P ] [pop c ] [G ] [dip F ] genrec
+ A == [P ] [pop []] [G ] [dip swap cons] genrec
+ C == [not] [pop c ] [uncons swap] [dip F ] genrec
Para-, ?-, ?-
~~~~~~~~~~~~~
::
- P == c swap [P ] [pop] [[F ] dupdip G ] primrec
- ? == [] swap [P ] [pop] [[swap cons] dupdip G ] primrec
- ? == c swap [not] [pop] [[F ] dupdip uncons swap] primrec
+ P == c swap [P ] [pop] [[F ] dupdip G ] primrec
+ ? == [] swap [P ] [pop] [[swap cons] dupdip G ] primrec
+ ? == c swap [not] [pop] [[F ] dupdip uncons swap] primrec
Appendix: Fun with Symbols
--------------------------
::
- |[ (c, F), (G, P) ]| == (|c, F|) • [(G, P)]
+ |[ (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>`__
+`“Bananas, Lenses, & Barbed
+Wire” <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
::
- (|...|) [(...)] [<...>]
+ (|...|) [(...)] [<...>]
I think they are having slightly too much fun with the symbols. However,
-"Too much is always better than not enough."
+“Too much is always better than not enough.”
For now, there is no way to define new functions from within the Joy
language. All functions (and the interpreter) all accept and return a
dictionary parameter (in addition to the stack and expression) so that
-we can implement e.g. a function that adds new functions to the
-dictionary. However, there's no function that does that. Adding a new
+we can implement e.g. a function that adds new functions to the
+dictionary. However, there’s no function that does that. Adding a new
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.
::
- sum == 0 swap [+] step
- size == 0 swap [pop ++] step
+ sum == 0 swap [+] step
+ size == 0 swap [pop ++] step
An efficient ``sum`` function is already in the library. But for
``size`` we can use a “compiled” version hand-written in Python to speed
::
- foo bar
+ foo bar
Operations have inputs and outputs. The outputs of ``foo`` must be
-compatible in "arity", type, and shape with the inputs of ``bar``.
+compatible in “arity”, type, and shape with the inputs of ``bar``.
Branch
------
::
- boolean [F] [T] branch
+ boolean [F] [T] branch
- t [F] [T] branch
- ----------------------
- T
+ t [F] [T] branch
+ ----------------------
+ T
- f [F] [T] branch
- ----------------------
- F
+ f [F] [T] branch
+ ----------------------
+ F
- branch == unit cons swap pick i
+ branch == unit cons swap pick i
- boolean [F] [T] branch
- boolean [F] [T] unit cons swap pick i
- boolean [F] [[T]] cons swap pick i
- boolean [[F] [T]] swap pick i
- [[F] [T]] boolean pick i
- [F-or-T] i
+ boolean [F] [T] branch
+ boolean [F] [T] unit cons swap pick i
+ boolean [F] [[T]] cons swap pick i
+ boolean [[F] [T]] swap pick i
+ [[F] [T]] boolean pick i
+ [F-or-T] i
Given some branch function ``G``:
::
- G == [F] [T] branch
+ G == [F] [T] branch
Used in a sequence like so:
::
- foo G bar
+ foo G bar
The inputs and outputs of ``F`` and ``T`` must be compatible with the
outputs for ``foo`` and the inputs of ``bar``, respectively.
::
- foo F bar
+ foo F bar
- foo T bar
+ foo T bar
``ifte``
~~~~~~~~
Often it will be easier on the programmer to write branching code with
the predicate specified in a quote. The ``ifte`` combinator provides
-this (``T`` for "then" and ``E`` for "else"):
+this (``T`` for “then” and ``E`` for “else”):
::
- [P] [T] [E] ifte
+ [P] [T] [E] ifte
Defined in terms of ``branch``:
::
- ifte == [nullary not] dip branch
+ ifte == [nullary not] dip branch
In this case, ``P`` must be compatible with the stack and return a
Boolean value, and ``T`` and ``E`` both must be compatible with the
preceeding and following functions, as described above for ``F`` and
``T``. (Note that in the current implementation we are depending on
-Python for the underlying semantics, so the Boolean value doesn't *have*
-to be Boolean because Python's rules for "truthiness" will be used to
+Python for the underlying semantics, so the Boolean value doesn’t *have*
+to be Boolean because Python’s rules for “truthiness” will be used to
evaluate it. I reflect this in the structure of the stack effect comment
of ``branch``, it will only accept Boolean values, and in the definition
of ``ifte`` above by including ``not`` in the quote, which also has the
::
- boolean [Q] loop
+ boolean [Q] loop
- t [Q] loop
- ----------------
- Q [Q] loop
+ t [Q] loop
+ ----------------
+ Q [Q] loop
- ... f [Q] loop
- --------------------
- ...
+ ... f [Q] loop
+ --------------------
+ ...
The ``loop`` combinator generates a copy of itself in the true branch.
This is the hallmark of recursive defintions. In Thun there is no
::
- loop == [] swap [dup dip loop] cons branch
+ loop == [] swap [dup dip loop] cons branch
- boolean [Q] loop
- boolean [Q] [] swap [dup dip loop] cons branch
- boolean [] [Q] [dup dip loop] cons branch
- boolean [] [[Q] dup dip loop] branch
+ boolean [Q] loop
+ boolean [Q] [] swap [dup dip loop] cons branch
+ boolean [] [Q] [dup dip loop] cons branch
+ boolean [] [[Q] dup dip loop] branch
In action the false branch does nothing while the true branch does:
::
- t [] [[Q] dup dip loop] branch
- [Q] dup dip loop
- [Q] [Q] dip loop
- Q [Q] loop
+ t [] [[Q] dup dip loop] branch
+ [Q] dup dip loop
+ [Q] [Q] dip loop
+ Q [Q] loop
Because ``loop`` expects and consumes a Boolean value, the ``Q``
function must be compatible with the previous stack *and itself* with a
::
- Q == G b
+ Q == G b
- Q [Q] loop
- G b [Q] loop
- G Q [Q] loop
- G G b [Q] loop
- G G Q [Q] loop
- G G G b [Q] loop
- G G G
+ Q [Q] loop
+ G b [Q] loop
+ G Q [Q] loop
+ G G b [Q] loop
+ G G Q [Q] loop
+ G G G b [Q] loop
+ G G G
``while``
~~~~~~~~~
::
- [P] [B] while
- --------------------------------------
- [P] nullary [B [P] nullary] loop
+ [P] [B] while
+ --------------------------------------
+ [P] nullary [B [P] nullary] loop
- while == swap [nullary] cons dup dipd concat loop
+ while == swap [nullary] cons dup dipd concat loop
- [P] [B] while
- [P] [B] swap [nullary] cons dup dipd concat loop
- [B] [P] [nullary] cons dup dipd concat loop
- [B] [[P] nullary] dup dipd concat loop
- [B] [[P] nullary] [[P] nullary] dipd concat loop
- [P] nullary [B] [[P] nullary] concat loop
- [P] nullary [B [P] nullary] loop
+ [P] [B] while
+ [P] [B] swap [nullary] cons dup dipd concat loop
+ [B] [P] [nullary] cons dup dipd concat loop
+ [B] [[P] nullary] dup dipd concat loop
+ [B] [[P] nullary] [[P] nullary] dipd concat loop
+ [P] nullary [B] [[P] nullary] concat loop
+ [P] nullary [B [P] nullary] loop
Parallel
--------
The *parallel* operation indicates that two (or more) functions *do not
interfere* with each other and so can run in parallel. The main
difficulty in this sort of thing is orchestrating the recombining
-("join" or "wait") of the results of the functions after they finish.
+(“join” or “wait”) of the results of the functions after they finish.
The current implementaions and the following definitions *are not
-actually parallel* (yet), but there is no reason they couldn't be
-reimplemented in terms of e.g. Python threads. I am not concerned with
+actually parallel* (yet), but there is no reason they couldn’t be
+reimplemented in terms of e.g. Python threads. I am not concerned with
performance of the system just yet, only the elegance of the code it
allows us to write.
::
- ... x [A] [B] cleave
- ---------------------------------------------------------
- ... [x ...] [A] infra first [x ...] [B] infra first
- ---------------------------------------------------------
- ... a b
+ ... x [A] [B] cleave
+ ---------------------------------------------------------
+ ... [x ...] [A] infra first [x ...] [B] infra first
+ ---------------------------------------------------------
+ ... a b
The ``cleave`` combinator expects a value and two quotes and it executes
-each quote in "separate universes" such that neither can affect the
+each quote in “separate universes” such that neither can affect the
other, then it takes the first item from the stack in each universe and
replaces the value and quotes with their respective results.
-(I think this corresponds to the "fork" operator, the little
+(I think this corresponds to the “fork” operator, the little
upward-pointed triangle, that takes two functions ``A :: x -> a`` and
``B :: x -> b`` and returns a function ``F :: x -> (a, b)``, in Conal
-Elliott's "Compiling to Categories" paper, et. al.)
+Elliott’s “Compiling to Categories” paper, et. al.)
Just a thought, if you ``cleave`` two jobs and one requires more time to
-finish than the other you'd like to be able to assign resources
+finish than the other you’d like to be able to assign resources
accordingly so that they both finish at the same time.
-"Apply" Functions
+“Apply” Functions
~~~~~~~~~~~~~~~~~
There are also ``app2`` and ``app3`` which run a single quote on more
::
- ... y x [Q] app2
- ---------------------------------------------------------
- ... [y ...] [Q] infra first [x ...] [Q] infra first
+ ... y x [Q] app2
+ ---------------------------------------------------------
+ ... [y ...] [Q] infra first [x ...] [Q] infra first
- ... z y x [Q] app3
- ---------------------------------
- ... [z ...] [Q] infra first
- [y ...] [Q] infra first
- [x ...] [Q] infra first
+ ... z y x [Q] app3
+ ---------------------------------
+ ... [z ...] [Q] infra first
+ [y ...] [Q] infra first
+ [x ...] [Q] infra first
Because the quoted program can be ``i`` we can define ``cleave`` in
terms of ``app2``:
::
- cleave == [i] app2 [popd] dip
+ cleave == [i] app2 [popd] dip
-(I'm not sure why ``cleave`` was specified to take that value, I may
+(I’m not sure why ``cleave`` was specified to take that value, I may
make a combinator that does the same thing but without expecting a
value.)
::
- clv == [i] app2
+ clv == [i] app2
- [A] [B] clv
- ------------------
- a b
+ [A] [B] clv
+ ------------------
+ a b
``map``
~~~~~~~
::
- [a b c ...] [Q] map
+ [a b c ...] [Q] map
-There is no reason why the implementation of ``map`` couldn't distribute
-the ``Q`` function over e.g. a pool of worker CPUs.
+There is no reason why the implementation of ``map`` couldn’t distribute
+the ``Q`` function over e.g. a pool of worker CPUs.
``pam``
~~~~~~~
::
- pam == [i] map
+ pam == [i] map
This can be used to run any number of programs separately on the current
stack and combine their (first) outputs in a result list.
::
- [[A] [B] [C] ...] [i] map
- -------------------------------
- [ a b c ...]
+ [[A] [B] [C] ...] [i] map
+ -------------------------------
+ [ a b c ...]
Handling Other Kinds of Join
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``cleave`` operators and others all have pretty brutal join
semantics: everything works and we always wait for every
sub-computation. We can imagine a few different potentially useful
-patterns of "joining" results from parallel combinators.
+patterns of “joining” results from parallel combinators.
first-to-finish
^^^^^^^^^^^^^^^
The other sub-programs would be cancelled.
-"Fulminators"
+“Fulminators”
^^^^^^^^^^^^^
-Also known as "Futures" or "Promises" (by *everybody* else. "Fulinators"
+Also known as “Futures” or “Promises” (by *everybody* else. “Fulinators”
is what I was going to call them when I was thinking about implementing
them in Thun.)
-The runtime could be amended to permit "thunks" representing the results
+The runtime could be amended to permit “thunks” representing the results
of in-progress computations to be left on the stack and picked up by
subsequent functions. These would themselves be able to leave behind
-more "thunks", the values of which depend on the eventual resolution of
+more “thunks”, the values of which depend on the eventual resolution of
the values of the previous thunks.
-In this way you can create "chains" (and more complex shapes) out of
+In this way you can create “chains” (and more complex shapes) out of
normal-looking code that consist of a kind of call-graph interspersed
-with "asyncronous" ... events?
+with “asyncronous” … events?
In any case, until I can find a rigorous theory that shows that this
-sort of thing works perfectly in Joy code I'm not going to worry about
+sort of thing works perfectly in Joy code I’m not going to worry about
it. (And I think the Categories can deal with it anyhow? Incremental
evaluation, yeah?)
::
- BTree :: [] | [key value BTree BTree]
+ 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
A Function to Traverse this Structure
-------------------------------------
-Let's take a crack at writing a function that can recursively iterate or
+Let’s take a crack at writing a function that can recursively iterate or
traverse these trees.
Base case ``[]``
::
- BTree-iter == [not] [E] [R0] [R1] genrec
+ BTree-iter == [not] [E] [R0] [R1] genrec
-And since there's nothing at this node, we just ``pop`` it:
+And since there’s nothing at this node, we just ``pop`` it:
::
- BTree-iter == [not] [pop] [R0] [R1] genrec
+ BTree-iter == [not] [pop] [R0] [R1] genrec
Node case ``[key value left right]``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- BTree-iter == [not] [pop] [R0] [R1] genrec
- == [not] [pop] [R0 [BTree-iter] R1] ifte
+ BTree-iter == [not] [pop] [R0] [R1] genrec
+ == [not] [pop] [R0 [BTree-iter] R1] ifte
-Let's look at it *in situ*:
+Let’s look at it *in situ*:
::
- [key value left right] R0 [BTree-iter] R1
+ [key value left right] R0 [BTree-iter] R1
Processing the current node.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [key value left right] [F] dupdip [BTree-iter] R1
- [key value left right] F [key value left right] [BTree-iter] R1
+ [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``:
+For example, if we’re getting all the keys ``F`` would be ``first``:
::
- R0 == [first] dupdip
+ 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
+ [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
^^^^^
::
- 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]
+ 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
+ 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
+ R1 == [rest rest] dip step
Putting it together
^^^^^^^^^^^^^^^^^^^
::
- BTree-iter == [not] [pop] [[F] dupdip] [[rest rest] dip step] genrec
+ 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
+ BTree-iter == [not] [pop] [[F] dupdip rest rest] [step] genrec
(And ``[step] genrec`` is such a cool and suggestive combinator!)
::
- [F] BTree-iter == [not] [pop] [[F] dupdip rest rest] [step] genrec
+ [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
+ [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
+ BTree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec
.. code:: ipython2
Adding Nodes to the BTree
=========================
-Let's consider adding nodes to a BTree structure.
+Let’s consider adding nodes to a BTree structure.
::
- BTree value key BTree-add == BTree
+ BTree value key BTree-add == BTree
Adding to an empty node.
^^^^^^^^^^^^^^^^^^^^^^^^
::
- BTree-add == [popop not] [[pop] dipd BTree-new] [R0] [R1] genrec
+ BTree-add == [popop not] [[pop] dipd BTree-new] [R0] [R1] genrec
Where ``BTree-new`` is:
::
- value key BTree-new == [key value [] []]
+ value key BTree-new == [key value [] []]
- value key swap [[] []] cons cons
- key value [[] []] cons cons
- key [value [] []] cons
- [key value [] []]
+ value key swap [[] []] cons cons
+ key value [[] []] cons cons
+ key [value [] []] cons
+ [key value [] []]
- BTree-new == swap [[] []] cons cons
+ BTree-new == swap [[] []] cons cons
.. code:: ipython2
(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
+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.
+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
+ [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
+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] == []
+ [R0] == []
A predicate to compare keys.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The first thing we need to do is compare the the key we're adding to see
+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
+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] 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
+ [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
+ P > == pop roll> pop first >
+ P < == pop roll> pop first <
+ P == pop roll> pop first
.. code:: ipython2
True .
-If the key we're adding is greater than the node's key.
+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)
::
- [key_n value_n left right] value key [BTree-add] T == [key_n value_n left (BTree-add key value right)]
+ [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
+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
+ 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
+ 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
+ K == cons cons dipdd
And:
::
- [key_n value_n left right] [value key [BTree-add] K] infra
+ [key_n value_n left right] [value key [BTree-add] K] infra
Derive ``T``.
^^^^^^^^^^^^^
-So now we're at getting from this to this:
+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
+ [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
+ value key [BTree-add] T == [value key [BTree-add] K] infra
+ T == [ K] cons cons cons infra
.. code:: ipython2
['k' 'v' 'l' 0 'kk' 'vv' 'r'] .
-If the key we're adding is less than the node's key.
+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
+ [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
::
- Te == [cons cons dipd] cons cons cons infra
+ 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
+ ccons == cons cons
+ T == [ccons dipdd] ccons cons infra
+ Te == [ccons dipd] ccons cons infra
But whatever.
::
- [key_n value_n left right] value key [BTree-add] Ee
- ...
- [key value left right]
+ [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
+ 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]
+ [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
::
- BTree-add == [popop not] [[pop] dipd BTree-new] [] [[P >] [T] [E] ifte] genrec
+ 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-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
+ BTree-add == [popop not] [[pop] dipd BTree-new] [] [[P >] [T] [E] ifte] genrec
.. code:: ipython2
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 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.
``cmp`` combinator
==================
-Instead of all this mucking about with nested ``ifte`` let's just go
+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
+ G
- a b [G] [E] [L] cmp
- ------------------------- a = b
- E
+ a b [G] [E] [L] cmp
+ ------------------------- a = b
+ E
- a b [G] [E] [L] cmp
- ------------------------- a < b
- L
+ 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
+ [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
+ 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
+ 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
+ [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<
+ [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
+ BTree-add == [popop not] [[pop] dipd BTree-new] [] [P [T>] [E] [T<] cmp] genrec
.. code:: ipython2
::
- 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
+ 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
+ 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
========================================================
::
- BTree-iter-order == [not] [pop] [R0 [BTree-iter] R1] ifte
+ 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
+ [key value left right] R0 [BTree-iter-order] R1
Process the left child.
^^^^^^^^^^^^^^^^^^^^^^^
::
- [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
+ [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]
+ [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:
+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]
+ 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.
+``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]
+ 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.
^^^^^^^^^^^^^^^^^^^^^^^^
::
- 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]
+ 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
+ left BTree-iter-order key right [BTree-iter-order] i
+ left BTree-iter-order key right BTree-iter-order
Defining ``BTree-iter-order``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- R1 == [cons dip] dupdip [[F] dupdip] dip [rest rest rest first] dip i
+ R1 == [cons dip] dupdip [[F] dupdip] dip [rest rest rest first] dip i
-Let's do a little semantic factoring:
+Let’s do a little semantic factoring:
::
- fourth == rest rest rest first
+ fourth == rest rest rest first
- proc_left == [cons dip] dupdip
- proc_current == [[F] dupdip] dip
- proc_right == [fourth] dip i
+ 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
+ BTree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] genrec
Now we can sort sequences.
Getting values by key
=====================
-Let's derive a function that accepts a tree and a key and returns the
+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
+ tree key BTree-get
+ ------------------------
+ value
The base case ``[]``
^^^^^^^^^^^^^^^^^^^^
::
- BTree-get == [pop not] [E] [R0] [R1] genrec
+ 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.)
+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
+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 in tree
+ value
- tree key [E] BTree-get
- ---------------------------- key not in tree
- tree key E
+ tree key [E] BTree-get
+ ---------------------------- key not in tree
+ tree key E
Now we define:
::
- BTree-get == [pop not] swap [R0] [R1] genrec
+ 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
::
- tree key [E] [pop not] swap [R0] [R1] genrec
- tree key [pop not] [E] [R0] [R1] genrec
+ 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
+ [pop not] [E] [R0] [R1] genrec
Node case ``[key value left right]``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [key value left right] key R0 [BTree-get] 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
+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
+ [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
+ 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:
+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<
+ [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
+ [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
+ 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
+ [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
+ [key_n value_n left right] key [BTree-get] E == value_n
- E == popop second
+ 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
+ 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
+ BTree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
.. code:: ipython2
BTree-delete
============
-Now let's write a function that can return a tree datastructure with a
+Now let’s write a function that can return a tree datastructure with a
key, value pair deleted:
::
- tree key BTree-delete
- ---------------------------
- tree
+ tree key BTree-delete
+ ---------------------------
+ tree
If the key is not in tree it just returns the tree unchanged.
::
- BTree-Delete == [pop not] swap [R0] [R1] genrec
+ BTree-Delete == [pop not] swap [R0] [R1] genrec
::
- [Er] BTree-delete
- -------------------------------------
- [pop not] [Er] [R0] [R1] genrec
+ [Er] BTree-delete
+ -------------------------------------
+ [pop not] [Er] [R0] [R1] genrec
::
- [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<
+ [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<
Now we get to figure out the recursive case:
::
- w/ D == [pop not] [Er] [R0] [R1] genrec
+ w/ D == [pop not] [Er] [R0] [R1] genrec
- [node_key node_value left right] key R0 [D] R1
- [node_key node_value left right] key over first swap dup [D] R1
- [node_key node_value left right] node_key key key [D] R1
+ [node_key node_value left right] key R0 [D] R1
+ [node_key node_value left right] key over first swap dup [D] R1
+ [node_key node_value left right] node_key key key [D] R1
And then:
::
- [node_key node_value left right] node_key key key [D] R1
- [node_key node_value left right] node_key key key [D] cons roll> [T>] [E] [T<] cmp
- [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
- [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
+ [node_key node_value left right] node_key key key [D] R1
+ [node_key node_value left right] node_key key key [D] cons roll> [T>] [E] [T<] cmp
+ [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
+ [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
Now this:;
::
- [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
+ [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
Becomes one of these three:;
::
- [node_key node_value left right] [key D] T>
- [node_key node_value left right] [key D] E
- [node_key node_value left right] [key D] T<
+ [node_key node_value left right] [key D] T>
+ [node_key node_value left right] [key D] E
+ [node_key node_value left right] [key D] T<
Greater than case and less than case
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- [node_key node_value left right] [key D] T>
- -------------------------------------------------
- [node_key node_value left key D right]
+ [node_key node_value left right] [key D] T>
+ -------------------------------------------------
+ [node_key node_value left key D right]
First:
::
- right left node_value node_key [key D] dipd
- right left key D node_value node_key
- right left' node_value node_key
+ right left node_value node_key [key D] dipd
+ right left key D node_value node_key
+ right left' node_value node_key
Ergo:
::
- [node_key node_value left right] [key D] [dipd] cons infra
+ [node_key node_value left right] [key D] [dipd] cons infra
So:
::
- T> == [dipd] cons infra
- T< == [dipdd] cons infra
+ T> == [dipd] cons infra
+ T< == [dipdd] cons infra
The else case
~~~~~~~~~~~~~
::
- [node_key node_value left right] [key D] E
+ [node_key node_value left right] [key D] E
-We have to handle three cases, so let's use ``cond``.
+We have to handle three cases, so let’s use ``cond``.
The first two cases are symmetrical, if we only have one non-empty child
node return it.
::
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [default]
- ] cond
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [default]
+ ] cond
(If both child nodes are empty return an empty node.)
::
- default == [E'] cons infra
+ default == [E'] cons infra
- [node_key node_value left right] [key D] default
- [node_key node_value left right] [key D] [E'] cons infra
- [node_key node_value left right] [[key D] E'] infra
+ [node_key node_value left right] [key D] default
+ [node_key node_value left right] [key D] [E'] cons infra
+ [node_key node_value left right] [[key D] E'] infra
- right left node_value node_key [key D] E'
+ right left node_value node_key [key D] E'
If both child nodes are non-empty, we find the highest node in our lower
sub-tree, take its key and value to replace (delete) our own, then get
symmetrical options. Over a lot of deletions this might make the tree
more unbalanced. Oh well.)
-First things first, we no longer need this node's key and value:
+First things first, we no longer need this node’s key and value:
::
- right left node_value node_key [key D] roll> popop E''
- right left [key D] node_value node_key popop E''
- right left [key D] E''
+ right left node_value node_key [key D] roll> popop E''
+ right left [key D] node_value node_key popop E''
+ right left [key D] E''
Then we have to we find the highest (right-most) node in our lower
(left) sub-tree:
::
- right left [key D] E''
+ right left [key D] E''
Ditch the key:
::
- right left [key D] rest E'''
- right left [D] E'''
+ right left [key D] rest E'''
+ right left [D] E'''
Find the right-most node:
::
- right left [D] [dup W] dip E''''
- right left dup W [D] E''''
- right left left W [D] E''''
+ right left [D] [dup W] dip E''''
+ right left dup W [D] E''''
+ right left left W [D] E''''
Consider:
::
- left W
+ left W
We know left is not empty:
::
- [L_key L_value L_left L_right] W
+ [L_key L_value L_left L_right] W
We want to keep extracting the right node as long as it is not empty:
::
- left [P] [B] while W'
+ left [P] [B] while W'
The predicate:
::
- [L_key L_value L_left L_right] P
- [L_key L_value L_left L_right] fourth
- L_right
-
+ [L_key L_value L_left L_right] P
+ [L_key L_value L_left L_right] fourth
+ L_right
+
(This has a bug, can run on ``[]`` so must be guarded:
::
- if_not_empty == [] swap [] ifte
- ?fourth == [fourth] if_not_empty
- W.rightmost == [?fourth] [fourth] while
+ if_not_empty == [] swap [] ifte
+ ?fourth == [fourth] if_not_empty
+ W.rightmost == [?fourth] [fourth] while
The body is also ``fourth``:
::
- left [fourth] [fourth] while W'
- rightest W'
+ left [fourth] [fourth] while W'
+ rightest W'
We know rightest is not empty:
::
- [R_key R_value R_left R_right] W'
- [R_key R_value R_left R_right] uncons uncons pop
- R_key [R_value R_left R_right] uncons pop
- R_key R_value [R_left R_right] pop
- R_key R_value
+ [R_key R_value R_left R_right] W'
+ [R_key R_value R_left R_right] uncons uncons pop
+ R_key [R_value R_left R_right] uncons pop
+ R_key R_value [R_left R_right] pop
+ R_key R_value
So:
::
- W == [fourth] [fourth] while uncons uncons pop
+ W == [fourth] [fourth] while uncons uncons pop
And:
::
- right left left W [D] E''''
- right left R_key R_value [D] E''''
+ right left left W [D] E''''
+ right left R_key R_value [D] E''''
Final stretch. We want to end up with something like:
::
- right left [R_key D] i R_value R_key
- right left R_key D R_value R_key
- right left' R_value R_key
+ right left [R_key D] i R_value R_key
+ right left R_key D R_value R_key
+ right left' R_value R_key
If we adjust our definition of ``W`` to include ``over`` at the end:
::
- W == [fourth] [fourth] while uncons uncons pop over
+ W == [fourth] [fourth] while uncons uncons pop over
That will give us:
::
- right left R_key R_value R_key [D] E''''
+ right left R_key R_value R_key [D] E''''
- right left R_key R_value R_key [D] cons dipdd E'''''
- right left R_key R_value [R_key D] dipdd E'''''
- right left R_key D R_key R_value E'''''
- right left' R_key R_value E'''''
- right left' R_key R_value swap
- right left' R_value R_key
+ right left R_key R_value R_key [D] cons dipdd E'''''
+ right left R_key R_value [R_key D] dipdd E'''''
+ right left R_key D R_key R_value E'''''
+ right left' R_key R_value E'''''
+ right left' R_key R_value swap
+ right left' R_value R_key
So:
::
- E' == roll> popop E''
+ E' == roll> popop E''
- E'' == rest E'''
+ E'' == rest E'''
- E''' == [dup W] dip E''''
+ E''' == [dup W] dip E''''
- E'''' == cons dipdd swap
+ E'''' == cons dipdd swap
Substituting:
::
- W == [fourth] [fourth] while uncons uncons pop over
- E' == roll> popop rest [dup W] dip cons dipdd swap
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [[E'] cons infra]
- ] cond
+ W == [fourth] [fourth] while uncons uncons pop over
+ E' == roll> popop rest [dup W] dip cons dipdd swap
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [[E'] cons infra]
+ ] cond
Minor rearrangement:
::
- W == dup [fourth] [fourth] while uncons uncons pop over
- E' == roll> popop rest [W] dip cons dipdd swap
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [[E'] cons infra]
- ] cond
+ W == dup [fourth] [fourth] while uncons uncons pop over
+ E' == roll> popop rest [W] dip cons dipdd swap
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [[E'] cons infra]
+ ] cond
Refactoring
~~~~~~~~~~~
::
- W.rightmost == [fourth] [fourth] while
- W.unpack == uncons uncons pop
- E.clear_stuff == roll> popop rest
- E.delete == cons dipdd
- W == dup W.rightmost W.unpack over
- E.0 == E.clear_stuff [W] dip E.delete swap
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [[E.0] cons infra]
- ] cond
- T> == [dipd] cons infra
- T< == [dipdd] cons infra
- R0 == over first swap dup
- R1 == cons roll> [T>] [E] [T<] cmp
- BTree-Delete == [pop not] swap [R0] [R1] genrec
-
-By the standards of the code I've written so far, this is a *huge* Joy
+ W.rightmost == [fourth] [fourth] while
+ W.unpack == uncons uncons pop
+ E.clear_stuff == roll> popop rest
+ E.delete == cons dipdd
+ W == dup W.rightmost W.unpack over
+ E.0 == E.clear_stuff [W] dip E.delete swap
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [[E.0] cons infra]
+ ] cond
+ T> == [dipd] cons infra
+ T< == [dipdd] cons infra
+ R0 == over first swap dup
+ R1 == cons roll> [T>] [E] [T<] cmp
+ BTree-Delete == [pop not] swap [R0] [R1] genrec
+
+By the standards of the code I’ve written so far, this is a *huge* Joy
program.
.. code:: ipython2
The behavior of the ``[Er]`` function should maybe be different: either
just silently fail, or maybe implement some sort of function that can
grab the pending expression up to a sentinel value or something,
-allowing for a kind of "except"-ish control-flow?
+allowing for a kind of “except”-ish control-flow?
Then, once we have add, get, and delete we can see about abstracting
them.
Tree with node and list of trees.
=================================
-Let's consider a tree structure, similar to one described `"Why
-functional programming matters" by John
+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
::
- tree = [] | [node [tree*]]
+ tree = [] | [node [tree*]]
``treestep``
~~~~~~~~~~~~
::
- tree z [C] [N] treestep
+ 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
+ [] 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
::
- [node [tree*]] z [C] [N] treestep
- --------------------------------------- w/ K == z [C] [N] treestep
- node N [tree*] [K] map C
+ [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
+ 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
+ [node [tree*]] J
+ ------------------------------
+ node N [tree*] [K] map C
So ``J`` will have some form like:
::
- J == .. [N] .. [K] .. [C] ..
+ J == .. [N] .. [K] .. [C] ..
-Let's dive in. First, unquote the node and ``dip`` ``N``.
+Let’s dive in. First, unquote the node and ``dip`` ``N``.
::
- [node [tree*]] i [N] dip
- node [tree*] [N] dip
- node N [tree*]
+ [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
+ 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
+ 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
+ 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] [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
+ [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.
::
- TS0 == [not] swap unit [pop] swoncat
- TS1 == [dip] cons [i] swoncat
- treestep == swap [map] swoncat [TS1 [TS0] dip] dip genrec
+ TS0 == [not] swap unit [pop] swoncat
+ TS1 == [dip] cons [i] swoncat
+ treestep == swap [map] swoncat [TS1 [TS0] dip] dip genrec
.. code:: ipython2
::
- [] 0 [C] [N] treestep
- ---------------------------
- 0
+ [] 0 [C] [N] treestep
+ ---------------------------
+ 0
- [n [tree*]] 0 [sum +] [] treestep
- --------------------------------------------------
- n [tree*] [0 [sum +] [] treestep] map sum +
+ [n [tree*]] 0 [sum +] [] treestep
+ --------------------------------------------------
+ n [tree*] [0 [sum +] [] treestep] map sum +
.. code:: ipython2
A slight modification.
----------------------
-Let's simplify the tree datastructure definition slightly by just
+Let’s simplify the tree datastructure definition slightly by just
letting the children be the ``rest`` of the tree:
::
- tree = [] | [node tree*]
+ tree = [] | [node tree*]
The ``J`` function changes slightly.
::
- [node tree*] J
- ------------------------------
- node N [tree*] [K] map C
+ [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
+ [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
+ J == uncons [N] dip [K] map C
- K == [not] [pop z] [uncons [N] dip] [map C] genrec
+ K == [not] [pop z] [uncons [N] dip] [map C] genrec
.. code:: ipython2
::
- BTree = [] | [[key value] left right]
+ 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
+ node N [tree*] [K] map C
Plugging in our BTree structure:
::
- [key value] N [left right] [K] map C
+ [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
+ [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
3 23 23
-Doesn't work because ``map`` extracts the ``first`` item of whatever its
+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] 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 ]
+ [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
+ [] [flatten cons] [first] treestep
.. code:: ipython2
::
- key [[lk] [rk]] C
- key [[lk] [rk]] i
- key [lk] [rk] roll<
- [lk] [rk] key swons concat
- [lk] [key rk] concat
- [lk key rk]
+ 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
+ [] [i roll< swons concat] [first] treestep
.. code:: ipython2
Toy with it.
~~~~~~~~~~~~
-Let's reexamine:
+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] R0 [BTree-iter-order] R1
+ ...
+ left BTree-iter-order key value F right BTree-iter-order
- [key value left right] unstack swap
- key value left right swap
- key value right left
+ [key value left right] unstack 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]
+ 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
+ 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 == unstack swap
- R1 == [cons dipdd [F] dip] dupdip i
+ R0 == unstack swap
+ R1 == [cons dipdd [F] dip] dupdip i
- [key value left right] R0 [BTree-iter-order] R1
- [key value left right] unstack 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 left right] R0 [BTree-iter-order] R1
+ [key value left right] unstack 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
+ 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] [unstack swap] [[cons dipdd [F] dip] dupdip i] genrec
+ BTree-iter-order == [not] [pop] [unstack swap] [[cons dipdd [F] dip] dupdip i] genrec
Refactor ``cons cons``
^^^^^^^^^^^^^^^^^^^^^^
::
- cons2 == 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
+ 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
+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
::
- [[data] [child0] ... [childN-1]]
+ [[data] [child0] ... [childN-1]]
Suggests a general form of recursive iterator, but I have to go walk the
-dogs at the mo'.
+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
+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
+“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
::
- [data.. [c0] [c1] ... [cN]] [F C0 C1 ... CN] infil
- --------------------------------------------------------
- data F [c0] C0 [c1] C1 ... [cN] CN
-
-
+ [data.. [c0] [c1] ... [cN]] [F C0 C1 ... CN] infil
+ --------------------------------------------------------
+ data F [c0] C0 [c1] C1 ... [cN] CN
+
+
Just make ``[F]`` a parameter.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- BTree-iter == [not] [pop] [[F]] [R1] genrec
- == [not] [pop] [[F] [BTree-iter] R1] ifte
+ 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
+ [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:
+Let’s us define a parameterized form:
::
- BTree-iter == unit [not] [pop] roll< [R1] genrec
+ 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
+ [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
+ [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]
+ [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
+ [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] [unstack] dipd
- [key value left right] unstack [F] [BTree-iter]
- key value left right [F] [BTree-iter]
+ [key value left right] [F] [BTree-iter] [unstack] dipd
+ [key value left right] unstack [F] [BTree-iter]
+ key value left right [F] [BTree-iter]
- key value left right [F] [BTree-iter] R1.1
+ key value left right [F] [BTree-iter] R1.1
-Hmm...
+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] tuck
+ key value left right [BTree-iter] [F] [BTree-iter]
- [key value left right] [F] [BTree-iter] [unstack [roll>] dip] dipd
- [key value left right] unstack [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]
+ [key value left right] [F] [BTree-iter] [unstack [roll>] dip] dipd
+ [key value left right] unstack [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
+ 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
+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 ...
+ A == ... B ...
+ B == ... A ...
-That's fine. Circular datastructures can't be made though.
+That’s fine. Circular datastructures can’t be made though.
Treating Trees II: ``treestep``
===============================
-Let's consider a tree structure, similar to one described `"Why
-functional programming matters" by John
+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 followed by zero or more child trees. (The
asterisk is meant to indicate the `Kleene
::
- tree = [] | [node tree*]
+ tree = [] | [node tree*]
In the spirit of ``step`` we are going to define a combinator
``treestep`` which expects a tree and three additional items: a
::
- tree [B] [N] [C] treestep
+ tree [B] [N] [C] treestep
If the current tree node is empty then just execute ``B``:
::
- [] [B] [N] [C] treestep
- ---------------------------
- [] B
+ [] [B] [N] [C] treestep
+ ---------------------------
+ [] B
Otherwise, evaluate ``N`` on the node value, ``map`` the whole function
(abbreviated here as ``K``) over the child trees recursively, and then
::
- [node tree*] [B] [N] [C] treestep
- --------------------------------------- w/ K == [B] [N] [C] treestep
- node N [tree*] [K] map C
+ [node tree*] [B] [N] [C] treestep
+ --------------------------------------- w/ K == [B] [N] [C] treestep
+ node N [tree*] [K] map C
-(Later on we'll experiment with making ``map`` part of ``C`` so you can
+(Later on we’ll experiment with making ``map`` part of ``C`` so you can
use other combinators.)
Derive the recursive function.
::
- K == [not] [B] [R0] [R1] genrec
- == [not] [B] [R0 [K] R1] ifte
+ K == [not] [B] [R0] [R1] genrec
+ == [not] [B] [R0 [K] R1] ifte
So we just have to derive ``J``:
::
- J == R0 [K] R1
+ J == R0 [K] R1
The behavior of ``J`` is to accept a (non-empty) tree node and arrive at
the desired outcome.
::
- [node tree*] J
- ------------------------------
- node N [tree*] [K] map C
+ [node tree*] J
+ ------------------------------
+ node N [tree*] [K] map C
So ``J`` will have some form like:
::
- J == ... [N] ... [K] ... [C] ...
+ J == ... [N] ... [K] ... [C] ...
-Let's dive in. First, unquote the node and ``dip`` ``N``.
+Let’s dive in. First, unquote the node and ``dip`` ``N``.
::
- [node tree*] uncons [N] dip
- node [tree*] [N] dip
- node N [tree*]
+ [node tree*] uncons [N] dip
+ node [tree*] [N] dip
+ node N [tree*]
Next, ``map`` ``K`` over the child trees and combine with ``C``.
::
- node N [tree*] [K] map C
- node N [tree*] [K] map C
- node N [K.tree*] C
+ node N [tree*] [K] map C
+ node N [tree*] [K] map C
+ node N [K.tree*] C
So:
::
- J == uncons [N] dip [K] map C
+ J == uncons [N] dip [K] map C
Plug it in and convert to ``genrec``:
::
- K == [not] [B] [J ] ifte
- == [not] [B] [uncons [N] dip [K] map C] ifte
- == [not] [B] [uncons [N] dip] [map C] genrec
+ K == [not] [B] [J ] ifte
+ == [not] [B] [uncons [N] dip [K] map C] ifte
+ == [not] [B] [uncons [N] dip] [map C] genrec
Extract the givens to parameterize the program.
-----------------------------------------------
::
- [not] [B] [uncons [N] dip] [map C] genrec
- [B] [not] swap [uncons [N] dip] [map C] genrec
- [B] [uncons [N] dip] [[not] swap] dip [map C] genrec
- ^^^^^^^^^^^^^^^^
- [B] [[N] dip] [uncons] swoncat [[not] swap] dip [map C] genrec
- [B] [N] [dip] cons [uncons] swoncat [[not] swap] dip [map C] genrec
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ [not] [B] [uncons [N] dip] [map C] genrec
+ [B] [not] swap [uncons [N] dip] [map C] genrec
+ [B] [uncons [N] dip] [[not] swap] dip [map C] genrec
+ ^^^^^^^^^^^^^^^^
+ [B] [[N] dip] [uncons] swoncat [[not] swap] dip [map C] genrec
+ [B] [N] [dip] cons [uncons] swoncat [[not] swap] dip [map C] genrec
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Extract a couple of auxiliary definitions:
::
- TS.0 == [[not] swap] dip
- TS.1 == [dip] cons [uncons] swoncat
+ TS.0 == [[not] swap] dip
+ TS.1 == [dip] cons [uncons] swoncat
::
- [B] [N] TS.1 TS.0 [map C] genrec
- [B] [N] [map C] [TS.1 TS.0] dip genrec
- [B] [N] [C] [map] swoncat [TS.1 TS.0] dip genrec
+ [B] [N] TS.1 TS.0 [map C] genrec
+ [B] [N] [map C] [TS.1 TS.0] dip genrec
+ [B] [N] [C] [map] swoncat [TS.1 TS.0] dip genrec
The givens are all to the left so we have our definition.
::
- [not] [B] [uncons [N] dip] [map C] genrec
- [not] [B] [N] [dip] cons [uncons] swoncat [map C] genrec
- [B] [N] [not] roll> [dip] cons [uncons] swoncat [map C] genrec
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ [not] [B] [uncons [N] dip] [map C] genrec
+ [not] [B] [N] [dip] cons [uncons] swoncat [map C] genrec
+ [B] [N] [not] roll> [dip] cons [uncons] swoncat [map C] genrec
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Define ``treestep``
-------------------
::
- sumtree == [pop 0] [] [sum +] treestep
+ sumtree == [pop 0] [] [sum +] treestep
.. code:: ipython2
::
- [] [pop 0] [] [sum +] treestep
- ------------------------------------
- 0
+ [] [pop 0] [] [sum +] treestep
+ ------------------------------------
+ 0
.. code:: ipython2
::
- [n tree*] [pop 0] [] [sum +] treestep
- n [tree*] [[pop 0] [] [sum +] treestep] map sum +
- n [ ... ] sum +
- n m +
- n+m
+ [n tree*] [pop 0] [] [sum +] treestep
+ n [tree*] [[pop 0] [] [sum +] treestep] map sum +
+ n [ ... ] sum +
+ n m +
+ n+m
.. code:: ipython2
::
- Tree = [] | [[key value] left right]
+ Tree = [] | [[key value] left right]
What kind of functions can we write for this with our ``treestep``?
::
- node N [tree*] [K] map C
+ node N [tree*] [K] map C
Plugging in our BTree structure:
::
- [key value] N [left right] [K] map C
+ [key value] N [left right] [K] map C
Traversal
~~~~~~~~~
::
- [key value] first [left right] [K] map i
- key [value] [left right] [K] map i
- key [left right] [K] map i
- key [lkey rkey ] i
- key lkey rkey
+ [key value] first [left right] [K] map i
+ key [value] [left right] [K] map i
+ key [left right] [K] map i
+ key [lkey rkey ] i
+ key lkey rkey
-This doesn't quite work:
+This doesn’t quite work:
.. code:: ipython2
3 'B' 'B'
-Doesn't work because ``map`` extracts the ``first`` item of whatever its
+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] 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 ]
+ [key value] first [left right] [K] map flatten cons
+ key [left right] [K] map flatten cons
+ key [[lk] [rk] ] flatten cons
+ key [ lk rk ] cons
+ [key lk rk ]
So:
::
- [] [first] [flatten cons] treestep
+ [] [first] [flatten cons] treestep
.. code:: ipython2
::
- key [[lk] [rk]] C
- key [[lk] [rk]] i
- key [lk] [rk] roll<
- [lk] [rk] key swons concat
- [lk] [key rk] concat
- [lk key rk]
+ 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
+ [] [i roll< swons concat] [first] treestep
.. code:: ipython2
With ``treegrind``?
-------------------
-The ``treegrind`` function doesn't include the ``map`` combinator, so
+The ``treegrind`` function doesn’t include the ``map`` combinator, so
the ``[C]`` function must arrange to use some combinator on the quoted
recursive copy ``[K]``. With this function, the pattern for processing a
non-empty node is:
::
- node N [tree*] [K] C
+ node N [tree*] [K] C
Plugging in our BTree structure:
::
- [key value] N [left right] [K] C
+ [key value] N [left right] [K] C
.. code:: ipython2
[3 0] 'N' [2 0] 'N' [9 0] 'N' [5 0] 'N' [4 0] 'N' [8 0] 'N' [6 0] 'N' [7 0] 'N'
-Sum the nodes' keys.
+Sum the nodes’ keys.
.. code:: ipython2
::
- [B] [N] [C] treegrind
+ [B] [N] [C] treegrind
-We'll start by saying that the base-case (the key is not in the tree) is
+We’ll start by saying that the base-case (the key is not in the tree) is
user defined, and the per-node function is just the query key literal:
::
- [B] [query_key] [C] treegrind
+ [B] [query_key] [C] treegrind
This means we just have to define ``C`` from:
::
- [key value] query_key [left right] [K] C
+ [key value] query_key [left right] [K] C
-Let's try ``cmp``:
+Let’s try ``cmp``:
::
- C == P [T>] [E] [T<] cmp
+ C == P [T>] [E] [T<] cmp
- [key value] query_key [left right] [K] P [T>] [E] [T<] cmp
+ [key value] query_key [left right] [K] P [T>] [E] [T<] cmp
The predicate ``P``
~~~~~~~~~~~~~~~~~~~
::
- [key value] query_key [left right] [K] P
- [key value] query_key [left right] [K] roll<
- [key value] [left right] [K] query_key [roll< uncons swap] dip
+ [key value] query_key [left right] [K] P
+ [key value] query_key [left right] [K] roll<
+ [key value] [left right] [K] query_key [roll< uncons swap] dip
- [key value] [left right] [K] roll< uncons swap query_key
- [left right] [K] [key value] uncons swap query_key
- [left right] [K] key [value] swap query_key
- [left right] [K] [value] key query_key
+ [key value] [left right] [K] roll< uncons swap query_key
+ [left right] [K] [key value] uncons swap query_key
+ [left right] [K] key [value] swap query_key
+ [left right] [K] [value] key query_key
- P == roll< [roll< uncons swap] dip
+ P == roll< [roll< uncons swap] dip
(Possibly with a swap at the end? Or just swap ``T<`` and ``T>``.)
::
- [left right] [K] [value] key query_key [T>] [E] [T<] cmp
+ [left right] [K] [value] key query_key [T>] [E] [T<] cmp
Becomes one of these three:
::
- [left right] [K] [value] T>
- [left right] [K] [value] E
- [left right] [K] [value] T<
+ [left right] [K] [value] T>
+ [left right] [K] [value] E
+ [left right] [K] [value] T<
``E``
~~~~~
::
- E == roll> popop first
+ E == roll> popop first
``T<`` and ``T>``
~~~~~~~~~~~~~~~~~
::
- T< == pop [first] dip i
- T> == pop [second] dip i
+ T< == pop [first] dip i
+ T> == pop [second] dip i
Putting it together
-------------------
::
- T> == pop [first] dip i
- T< == pop [second] dip i
- E == roll> popop first
- P == roll< [roll< uncons swap] dip
+ T> == pop [first] dip i
+ T< == pop [second] dip i
+ E == roll> popop first
+ P == roll< [roll< uncons swap] dip
- Tree-get == [P [T>] [E] [T<] cmp] treegrind
+ Tree-get == [P [T>] [E] [T<] cmp] treegrind
To me, that seems simpler than the ``genrec`` version.
(... [3 4 ] 2 1 0 -- ... [1 2 ])
-Unification Works "in Reverse"
+Unification Works “in Reverse”
------------------------------
.. code:: ipython2
===================================
This notebook presents a simple type inferencer for Joy code. It can
-infer the stack effect of most Joy expressions. It's built largely by
+infer the stack effect of most Joy expressions. It’s built largely by
means of existing ideas and research. (A great overview of the existing
-knowledge is a talk `"Type Inference in Stack-Based Programming
-Languages" <http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/>`__
+knowledge is a talk `“Type Inference in Stack-Based Programming
+Languages” <http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/>`__
given by Rob Kleffner on or about 2017-03-10 as part of a course on the
history of programming languages.)
The notebook starts with a simple inferencer based on the work of Jaanus
Pöial which we then progressively elaborate to cover more Joy semantics.
-Along the way we write a simple "compiler" that emits Python code for
+Along the way we write a simple “compiler” that emits Python code for
what I like to call Yin functions. (Yin functions are those that only
rearrange values in stacks, as opposed to Yang functions that actually
work on the values themselves.)
-Part I: Pöial's Rules
+Part I: Pöial’s Rules
---------------------
-`"Typing Tools for Typeless Stack Languages" by Jaanus
+`“Typing Tools for Typeless Stack Languages” by Jaanus
Pöial <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.212.6026>`__
::
- @INPROCEEDINGS{Pöial06typingtools,
- author = {Jaanus Pöial},
- title = {Typing tools for typeless stack languages},
- booktitle = {In 23rd Euro-Forth Conference},
- year = {2006},
- pages = {40--46}
- }
+ @INPROCEEDINGS{Pöial06typingtools,
+ author = {Jaanus Pöial},
+ title = {Typing tools for typeless stack languages},
+ booktitle = {In 23rd Euro-Forth Conference},
+ year = {2006},
+ pages = {40--46}
+ }
First Rule
~~~~~~~~~~
::
- (a -- b)∘(-- d)
- ---------------------
- (a -- b d)
+ (a -- b)∘(-- d)
+ ---------------------
+ (a -- b d)
Second Rule
~~~~~~~~~~~
::
- (a --)∘(c -- d)
- ---------------------
- (c a -- d)
+ (a --)∘(c -- d)
+ ---------------------
+ (c a -- d)
Third Rule
~~~~~~~~~~
The third rule is actually two rules. These two rules deal with
composing functions when the second one will consume one of items the
first one produces. The two types must be
-`*unified* <https://en.wikipedia.org/wiki/Robinson's_unification_algorithm>`__
+`unified <https://en.wikipedia.org/wiki/Robinson's_unification_algorithm>`__
or a type conflict declared.
::
- (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
- -------------------------------
- (a -- b )∘(c -- d) t[i] == t[k] == u[j]
- ^
+ (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == t[k] == u[j]
+ ^
- (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
- -------------------------------
- (a -- b )∘(c -- d) t[i] == u[k] == u[j]
+ (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == u[k] == u[j]
-Let's work through some examples by hand to develop an intuition for the
+Let’s work through some examples by hand to develop an intuition for the
algorithm.
-There's a function in one of the other notebooks.
+There’s a function in one of the other notebooks.
::
- F == pop swap roll< rest rest cons cons
+ F == pop swap roll< rest rest cons cons
-It's all "stack chatter" and list manipulation so we should be able to
+It’s all “stack chatter” and list manipulation so we should be able to
deduce its type.
Stack Effect Comments
~~~~~~~~~~~~~~~~~~~~~
Joy function types will be represented by Forth-style stack effect
-comments. I'm going to use numbers instead of names to keep track of the
+comments. I’m going to use numbers instead of names to keep track of the
stack arguments. (A little bit like `De Bruijn
index <https://en.wikipedia.org/wiki/De_Bruijn_index>`__, at least it
reminds me of them):
::
- pop (1 --)
+ pop (1 --)
- swap (1 2 -- 2 1)
+ swap (1 2 -- 2 1)
- roll< (1 2 3 -- 2 3 1)
+ roll< (1 2 3 -- 2 3 1)
-These commands alter the stack but don't "look at" the values so these
-numbers represent an "Any type".
+These commands alter the stack but don’t “look at” the values so these
+numbers represent an “Any type”.
``pop swap``
~~~~~~~~~~~~
::
- (1 --) (1 2 -- 2 1)
+ (1 --) (1 2 -- 2 1)
Here we encounter a complication. The argument numbers need to be made
-unique among both sides. For this let's change ``pop`` to use 0:
+unique among both sides. For this let’s change ``pop`` to use 0:
::
- (0 --) (1 2 -- 2 1)
+ (0 --) (1 2 -- 2 1)
Following the second rule:
::
- (1 2 0 -- 2 1)
+ (1 2 0 -- 2 1)
``pop∘swap roll<``
~~~~~~~~~~~~~~~~~~
::
- (1 2 0 -- 2 1) (1 2 3 -- 2 3 1)
+ (1 2 0 -- 2 1) (1 2 3 -- 2 3 1)
-Let's re-label them:
+Let’s re-label them:
::
- (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
+ (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
Now we follow the rules.
::
- (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
- w/ {1a: 3b}
- (3b 2a 0a -- 2a ) (1b 2b -- 2b 3b 1b)
- w/ {2a: 2b}
- (3b 2b 0a -- ) (1b -- 2b 3b 1b)
+ (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
+ w/ {1a: 3b}
+ (3b 2a 0a -- 2a ) (1b 2b -- 2b 3b 1b)
+ w/ {2a: 2b}
+ (3b 2b 0a -- ) (1b -- 2b 3b 1b)
Here we must apply the second rule:
::
- (3b 2b 0a --) (1b -- 2b 3b 1b)
- -----------------------------------
- (1b 3b 2b 0a -- 2b 3b 1b)
+ (3b 2b 0a --) (1b -- 2b 3b 1b)
+ -----------------------------------
+ (1b 3b 2b 0a -- 2b 3b 1b)
Now we de-label the type, uh, labels:
::
- (1b 3b 2b 0a -- 2b 3b 1b)
+ (1b 3b 2b 0a -- 2b 3b 1b)
- w/ {
- 1b: 1,
- 3b: 2,
- 2b: 3,
- 0a: 0,
- }
+ w/ {
+ 1b: 1,
+ 3b: 2,
+ 2b: 3,
+ 0a: 0,
+ }
- (1 2 3 0 -- 3 2 1)
+ (1 2 3 0 -- 3 2 1)
And now we have the stack effect comment for ``pop∘swap∘roll<``.
Compiling ``pop∘swap∘roll<``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The simplest way to "compile" this function would be something like:
+The simplest way to “compile” this function would be something like:
.. code:: ipython2
::
- (1 2 3 0 -- 3 2 1)
+ (1 2 3 0 -- 3 2 1)
We should be able to directly write out a Python function like:
return (c, (b, (a, stack)))
This eliminates the internal work of the first version. Because this
-function only rearranges the stack and doesn't do any actual processing
+function only rearranges the stack and doesn’t do any actual processing
on the stack items themselves all the information needed to implement it
is in the stack effect comment.
::
- rest ( [1 ...] -- [...] )
+ rest ( [1 ...] -- [...] )
- cons ( 1 [...] -- [1 ...] )
+ cons ( 1 [...] -- [1 ...] )
``pop∘swap∘roll< rest``
~~~~~~~~~~~~~~~~~~~~~~~
::
- (1 2 3 0 -- 3 2 1) ([1 ...] -- [...])
+ (1 2 3 0 -- 3 2 1) ([1 ...] -- [...])
-Re-label (instead of adding left and right tags I'm just taking the next
+Re-label (instead of adding left and right tags I’m just taking the next
available index number for the right-side stack effect comment):
::
- (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
+ (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
Unify and update:
::
- (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
- w/ {1: [4 ...]}
- ([4 ...] 2 3 0 -- 3 2 ) ( -- [...])
+ (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
+ w/ {1: [4 ...]}
+ ([4 ...] 2 3 0 -- 3 2 ) ( -- [...])
Apply the first rule:
::
- ([4 ...] 2 3 0 -- 3 2) (-- [...])
- ---------------------------------------
- ([4 ...] 2 3 0 -- 3 2 [...])
+ ([4 ...] 2 3 0 -- 3 2) (-- [...])
+ ---------------------------------------
+ ([4 ...] 2 3 0 -- 3 2 [...])
And there we are.
``pop∘swap∘roll<∘rest rest``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Let's do it again.
+Let’s do it again.
::
- ([4 ...] 2 3 0 -- 3 2 [...]) ([1 ...] -- [...])
+ ([4 ...] 2 3 0 -- 3 2 [...]) ([1 ...] -- [...])
Re-label (the tails of the lists on each side each get their own label):
::
- ([4 .0.] 2 3 0 -- 3 2 [.0.]) ([5 .1.] -- [.1.])
+ ([4 .0.] 2 3 0 -- 3 2 [.0.]) ([5 .1.] -- [.1.])
Unify and update (note the opening square brackets have been omited in
-the substitution dict, this is deliberate and I'll explain below):
+the substitution dict, this is deliberate and I’ll explain below):
::
- ([4 .0.] 2 3 0 -- 3 2 [.0.] ) ([5 .1.] -- [.1.])
- w/ { .0.] : 5 .1.] }
- ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
+ ([4 .0.] 2 3 0 -- 3 2 [.0.] ) ([5 .1.] -- [.1.])
+ w/ { .0.] : 5 .1.] }
+ ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
How do we find ``.0.]`` in ``[4 .0.]`` and replace it with ``5 .1.]``
getting the result ``[4 5 .1.]``? This might seem hard, but because the
-underlying structure of the Joy list is a cons-list in Python it's
-actually pretty easy. I'll explain below.
+underlying structure of the Joy list is a cons-list in Python it’s
+actually pretty easy. I’ll explain below.
Next we unify and find our two terms are the same already: ``[5 .1.]``:
::
- ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
+ ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
Giving us:
::
- ([4 5 .1.] 2 3 0 -- 3 2) (-- [.1.])
+ ([4 5 .1.] 2 3 0 -- 3 2) (-- [.1.])
From here we apply the first rule and get:
::
- ([4 5 .1.] 2 3 0 -- 3 2 [.1.])
+ ([4 5 .1.] 2 3 0 -- 3 2 [.1.])
Cleaning up the labels:
::
- ([4 5 ...] 2 3 1 -- 3 2 [...])
+ ([4 5 ...] 2 3 1 -- 3 2 [...])
This is the stack effect of ``pop∘swap∘roll<∘rest∘rest``.
::
- ([4 5 ...] 2 3 1 -- 3 2 [...]) (1 [...] -- [1 ...])
+ ([4 5 ...] 2 3 1 -- 3 2 [...]) (1 [...] -- [1 ...])
Re-label:
::
- ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
+ ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
Unify:
::
- ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
- w/ { .1.] : .2.] }
- ([4 5 .2.] 2 3 1 -- 3 2 ) (6 -- [6 .2.])
- w/ {2: 6}
- ([4 5 .2.] 6 3 1 -- 3 ) ( -- [6 .2.])
+ ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
+ w/ { .1.] : .2.] }
+ ([4 5 .2.] 2 3 1 -- 3 2 ) (6 -- [6 .2.])
+ w/ {2: 6}
+ ([4 5 .2.] 6 3 1 -- 3 ) ( -- [6 .2.])
First rule:
::
- ([4 5 .2.] 6 3 1 -- 3 [6 .2.])
+ ([4 5 .2.] 6 3 1 -- 3 [6 .2.])
Re-label:
::
- ([4 5 ...] 2 3 1 -- 3 [2 ...])
+ ([4 5 ...] 2 3 1 -- 3 [2 ...])
Done.
::
- ([4 5 ...] 2 3 1 -- 3 [2 ...]) (1 [...] -- [1 ...])
+ ([4 5 ...] 2 3 1 -- 3 [2 ...]) (1 [...] -- [1 ...])
Re-label:
::
- ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.])
+ ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.])
Unify:
::
- ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.] )
- w/ { .2.] : 2 .1.] }
- ([4 5 .1.] 2 3 1 -- 3 ) (6 -- [6 2 .1.])
- w/ {3: 6}
- ([4 5 .1.] 2 6 1 -- ) ( -- [6 2 .1.])
+ ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.] )
+ w/ { .2.] : 2 .1.] }
+ ([4 5 .1.] 2 3 1 -- 3 ) (6 -- [6 2 .1.])
+ w/ {3: 6}
+ ([4 5 .1.] 2 6 1 -- ) ( -- [6 2 .1.])
First or second rule:
::
- ([4 5 .1.] 2 6 1 -- [6 2 .1.])
+ ([4 5 .1.] 2 6 1 -- [6 2 .1.])
Clean up the labels:
::
- ([4 5 ...] 2 3 1 -- [3 2 ...])
+ ([4 5 ...] 2 3 1 -- [3 2 ...])
And there you have it, the stack effect for
``pop∘swap∘roll<∘rest∘rest∘cons∘cons``.
::
- ([4 5 ...] 2 3 1 -- [3 2 ...])
+ ([4 5 ...] 2 3 1 -- [3 2 ...])
From this stack effect comment it should be possible to construct the
following Python code:
Representing Stack Effect Comments in Python
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-I'm going to use pairs of tuples of type descriptors, which will be
+I’m going to use pairs of tuples of type descriptors, which will be
integers or tuples of type descriptors:
.. code:: ipython2
At last we put it all together in a function ``C()`` that accepts two
stack effect comments and returns their composition (or raises and
-exception if they can't be composed due to type conflicts.)
+exception if they can’t be composed due to type conflicts.)
.. code:: ipython2
fg = compose(f, g)
return delabel(fg)
-Let's try it out.
+Let’s try it out.
.. code:: ipython2
Stack Functions
~~~~~~~~~~~~~~~
-Here's that trick to represent functions like ``rest`` and ``cons`` that
+Here’s that trick to represent functions like ``rest`` and ``cons`` that
manipulate stacks. We use a cons-list of tuples and give the tails their
own numbers. Then everything above already works.
::
- (( (3, 4), 1, 2, 0 ), ( 2, 1, 4 ))
- ( [4 ...] 2 3 0 -- 3 2 [...])
+ (( (3, 4), 1, 2, 0 ), ( 2, 1, 4 ))
+ ( [4 ...] 2 3 0 -- 3 2 [...])
The translation table, if you will, would be:
::
- {
- 3: 4,
- 4: ...],
- 1: 2,
- 2: 3,
- 0: 0,
- }
+ {
+ 3: 4,
+ 4: ...],
+ 1: 2,
+ 2: 3,
+ 0: 0,
+ }
.. code:: ipython2
::
- ([4 5 ...] 2 3 1 -- [3 2 ...])
- 3 4 5 1 2 0 2 1 5
+ ([4 5 ...] 2 3 1 -- [3 2 ...])
+ 3 4 5 1 2 0 2 1 5
Dealing with ``cons`` and ``uncons``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-However, if we try to compose e.g. ``cons`` and ``uncons`` it won't
+However, if we try to compose e.g. ``cons`` and ``uncons`` it won’t
work:
.. code:: ipython2
``unify()`` version 2
^^^^^^^^^^^^^^^^^^^^^
-The problem is that the ``unify()`` function as written doesn't handle
+The problem is that the ``unify()`` function as written doesn’t handle
the case when both terms are tuples. We just have to add a clause to
deal with this recursively:
::
- (_, (d, (c, ((a, (b, S0)), stack))))
+ (_, (d, (c, ((a, (b, S0)), stack))))
Remove the punctuation:
::
- _ d c (a, (b, S0))
+ _ d c (a, (b, S0))
Reverse the order and compare:
::
- (a, (b, S0)) c d _
- ((3, (4, 5 )), 1, 2, 0)
+ (a, (b, S0)) c d _
+ ((3, (4, 5 )), 1, 2, 0)
Eh?
::
- ((d, (c, S0)), stack)
- ((2, (1, 5 )), )
+ ((d, (c, S0)), stack)
+ ((2, (1, 5 )), )
This should make it pretty easy to write a Python function that accepts
the stack effect comment tuples and returns a new Python function
Python Identifiers
~~~~~~~~~~~~~~~~~~
-We want to substitute Python identifiers for the integers. I'm going to
+We want to substitute Python identifiers for the integers. I’m going to
repurpose ``joy.parser.Symbol`` class for this:
.. code:: ipython2
``doc_from_stack_effect()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-As a convenience I've implemented a function to convert the Python stack
+As a convenience I’ve implemented a function to convert the Python stack
effect comment tuples to reasonable text format. There are some details
in how this code works that related to stuff later in the notebook, so
-you should skip it for now and read it later if you're interested.
+you should skip it for now and read it later if you’re interested.
.. code:: ipython2
-Let's try it out:
+Let’s try it out:
.. code:: ipython2
With this, we have a partial Joy compiler that works on the subset of
-Joy functions that manipulate stacks (both what I call "stack chatter"
+Joy functions that manipulate stacks (both what I call “stack chatter”
and the ones that manipulate stacks on the stack.)
-I'm probably going to modify the definition wrapper code to detect
+I’m probably going to modify the definition wrapper code to detect
definitions that can be compiled by this partial compiler and do it
automatically. It might be a reasonable idea to detect sequences of
compilable functions in definitions that have uncompilable functions in
----------------------------------------
So far we have dealt with types of functions, those dealing with simple
-stack manipulation. Let's extend our machinery to deal with types of
+stack manipulation. Let’s extend our machinery to deal with types of
arguments.
-"Number" Type
+“Number” Type
~~~~~~~~~~~~~
Consider the definition of ``sqr``:
::
- sqr == dup mul
+ sqr == dup mul
The ``dup`` function accepts one *anything* and returns two of that:
::
- dup (1 -- 1 1)
+ dup (1 -- 1 1)
-And ``mul`` accepts two "numbers" (we're ignoring ints vs. floats vs.
-complex, etc., for now) and returns just one:
+And ``mul`` accepts two “numbers” (we’re ignoring ints vs. floats
+vs. complex, etc., for now) and returns just one:
::
- mul (n n -- n)
+ mul (n n -- n)
-So we're composing:
+So we’re composing:
::
- (1 -- 1 1)∘(n n -- n)
+ (1 -- 1 1)∘(n n -- n)
The rules say we unify 1 with ``n``:
::
- (1 -- 1 1)∘(n n -- n)
- --------------------------- w/ {1: n}
- (1 -- 1 )∘(n -- n)
+ (1 -- 1 1)∘(n n -- n)
+ --------------------------- w/ {1: n}
+ (1 -- 1 )∘(n -- n)
-This involves detecting that "Any type" arguments can accept "numbers".
+This involves detecting that “Any type” arguments can accept “numbers”.
If we were composing these functions the other way round this is still
the case:
::
- (n n -- n)∘(1 -- 1 1)
- --------------------------- w/ {1: n}
- (n n -- )∘( -- n n)
+ (n n -- n)∘(1 -- 1 1)
+ --------------------------- w/ {1: n}
+ (n n -- )∘( -- n n)
The important thing here is that the mapping is going the same way in
-both cases, from the "any" integer to the number
+both cases, from the “any” integer to the number
Distinguishing Numbers
~~~~~~~~~~~~~~~~~~~~~~
::
- mul (n2 n1 -- n3)
+ mul (n2 n1 -- n3)
- (1 -- 1 1)∘(n2 n1 -- n3)
- -------------------------------- w/ {1: n2}
- (n2 -- n2 )∘(n2 -- n3)
+ (1 -- 1 1)∘(n2 n1 -- n3)
+ -------------------------------- w/ {1: n2}
+ (n2 -- n2 )∘(n2 -- n3)
- (n2 n1 -- n3)∘(1 -- 1 1 )
- -------------------------------- w/ {1: n3}
- (n2 n1 -- )∘( -- n3 n3)
+ (n2 n1 -- n3)∘(1 -- 1 1 )
+ -------------------------------- w/ {1: n3}
+ (n2 n1 -- )∘( -- n3 n3)
Distinguishing Types
~~~~~~~~~~~~~~~~~~~~
-So we need separate domains of "any" numbers and "number" numbers, and
+So we need separate domains of “any” numbers and “number” numbers, and
we need to be able to ask the order of these domains. Now the notes on
the right side of rule three make more sense, eh?
::
- (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
- -------------------------------
- (a -- b )∘(c -- d) t[i] == t[k] == u[j]
- ^
+ (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == t[k] == u[j]
+ ^
- (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
- -------------------------------
- (a -- b )∘(c -- d) t[i] == u[k] == u[j]
+ (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == u[k] == u[j]
The indices ``i``, ``k``, and ``j`` are the number part of our labels
and ``t`` and ``u`` are the domains.
-By creative use of Python's "double underscore" methods we can define a
+By creative use of Python’s “double underscore” methods we can define a
Python class hierarchy of Joy types and use the ``issubclass()`` method
to establish domain ordering, as well as other handy behaviour that will
make it fairly easy to reuse most of the code above.
from itertools import permutations
-"Any" types can be specialized to numbers and stacks, but not vice
+“Any” types can be specialized to numbers and stacks, but not vice
versa:
.. code:: ipython2
Our crude `Numerical
Tower <https://en.wikipedia.org/wiki/Numerical_tower>`__ of *numbers* >
-*floats* > *integers* works as well (but we're not going to use it yet):
+*floats* > *integers* works as well (but we’re not going to use it yet):
.. code:: ipython2
^^^^^^^^^^^^^^^^^^^^^^^
The ``delabel()`` function needs an overhaul. It now has to keep track
-of how many labels of each domain it has "seen".
+of how many labels of each domain it has “seen”.
.. code:: ipython2
^^^^^^^^^^^^^^^^^^^^^^^^
Because the type labels represent themselves as valid Python identifiers
-the ``compile_()`` function doesn't need to generate them anymore:
+the ``compile_()`` function doesn’t need to generate them anymore:
.. code:: ipython2
return ((a4, (a3, s1)), stack)
-But it cannot magically create new functions that involve e.g. math and
+But it cannot magically create new functions that involve e.g. math and
such. Note that this is *not* a ``sqr`` function implementation:
.. code:: ipython2
return (n2, stack)
-(Eventually I should come back around to this becuase it's not tooo
+(Eventually I should come back around to this becuase it’s not tooo
difficult to exend this code to be able to compile e.g.
``n2 = mul(n1, n1)`` for ``mul`` with the right variable names and
insert it in the right place. It requires a little more support from the
::
- stack (... -- ... [...] )
- stack (... a -- ... a [a ...] )
- stack (... b a -- ... b a [a b ...])
+ stack (... -- ... [...] )
+ stack (... a -- ... a [a ...] )
+ stack (... b a -- ... b a [a b ...])
We would like to represent this in Python somehow. To do this we use a
simple, elegant trick.
::
- stack S -- ( S, S)
- stack (a, S) -- ( (a, S), (a, S))
- stack (a, (b, S)) -- ( (a, (b, S)), (a, (b, S)))
+ stack S -- ( S, S)
+ stack (a, S) -- ( (a, S), (a, S))
+ stack (a, (b, S)) -- ( (a, (b, S)), (a, (b, S)))
Instead of representing the stack effect comments as a single tuple
(with N items in it) we use the same cons-list structure to hold the
``stack∘uncons``
~~~~~~~~~~~~~~~~
-Let's try composing ``stack`` and ``uncons``. We want this result:
+Let’s try composing ``stack`` and ``uncons``. We want this result:
::
- stack∘uncons (... a -- ... a a [...])
+ stack∘uncons (... a -- ... a a [...])
The stack effects are:
::
- stack = S -- (S, S)
+ stack = S -- (S, S)
- uncons = ((a, Z), S) -- (Z, (a, S))
+ uncons = ((a, Z), S) -- (Z, (a, S))
Unifying:
::
- S -- (S, S) ∘ ((a, Z), S) -- (Z, (a, S ))
- w/ { S: (a, Z) }
- (a, Z) -- ∘ -- (Z, (a, (a, Z)))
+ S -- (S, S) ∘ ((a, Z), S) -- (Z, (a, S ))
+ w/ { S: (a, Z) }
+ (a, Z) -- ∘ -- (Z, (a, (a, Z)))
So:
::
- stack∘uncons == (a, Z) -- (Z, (a, (a, Z)))
+ stack∘uncons == (a, Z) -- (Z, (a, (a, Z)))
It works.
``stack∘uncons∘uncons``
~~~~~~~~~~~~~~~~~~~~~~~
-Let's try ``stack∘uncons∘uncons``:
+Let’s try ``stack∘uncons∘uncons``:
::
- (a, S ) -- (S, (a, (a, S ))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
+ (a, S ) -- (S, (a, (a, S ))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
- w/ { S: (b, Z) }
-
- (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
+ w/ { S: (b, Z) }
+
+ (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
- w/ { S`: (a, (a, (b, Z))) }
-
- (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), (a, (a, (b, Z)))) -- (Z, (b, (a, (a, (b, Z)))))
+ w/ { S`: (a, (a, (b, Z))) }
+
+ (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), (a, (a, (b, Z)))) -- (Z, (b, (a, (a, (b, Z)))))
- (a, (b, Z)) -- (Z, (b, (a, (a, (b, Z)))))
+ (a, (b, Z)) -- (Z, (b, (a, (a, (b, Z)))))
It works.
This function has to be modified to use the new datastructures and it is
no longer recursive, instead recursion happens as part of unification.
-Further, the first and second of Pöial's rules are now handled
+Further, the first and second of Pöial’s rules are now handled
automatically by the unification algorithm. (One easy way to see this is
that now an empty stack effect comment is represented by a
-``StackJoyType`` instance which is not "falsey" and so neither of the
-first two rules' ``if`` clauses will ever be ``True``. Later on I change
-the "truthiness" of ``StackJoyType`` to false to let e.g.
+``StackJoyType`` instance which is not “falsey” and so neither of the
+first two rules’ ``if`` clauses will ever be ``True``. Later on I change
+the “truthiness” of ``StackJoyType`` to false to let e.g.
``joy.utils.stack.concat`` work with our stack effect comment cons-list
tuples.)
raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
return update(s, (f_in, g_out))
-I don't want to rewrite all the defs myself, so I'll write a little
-conversion function instead. This is programmer's laziness.
+I don’t want to rewrite all the defs myself, so I’ll write a little
+conversion function instead. This is programmer’s laziness.
.. code:: ipython2
Part VI: Multiple Stack Effects
-------------------------------
-...
+…
.. code:: ipython2
Representing an Unbounded Sequence of Types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We can borrow a trick from `Brzozowski's Derivatives of Regular
+We can borrow a trick from `Brzozowski’s Derivatives of Regular
Expressions <https://en.wikipedia.org/wiki/Brzozowski_derivative>`__ to
-invent a new type of type variable, a "sequence type" (I think this is
-what they mean in the literature by that term...) or "`Kleene
-Star <https://en.wikipedia.org/wiki/Kleene_star>`__" type. I'm going to
+invent a new type of type variable, a “sequence type” (I think this is
+what they mean in the literature by that term…) or “`Kleene
+Star <https://en.wikipedia.org/wiki/Kleene_star>`__” type. I’m going to
represent it as a type letter and the asterix, so a sequence of zero or
more ``AnyJoyType`` variables would be:
::
- A*
+ A*
The ``A*`` works by splitting the universe into two alternate histories:
::
- A* -> 0 | A A*
+ A* -> 0 | A A*
The Kleene star variable disappears in one universe, and in the other it
turns into an ``AnyJoyType`` variable followed by itself again. We have
to return all universes (represented by their substitution dicts, the
-"unifiers") that don't lead to type conflicts.
+“unifiers”) that don’t lead to type conflicts.
Consider unifying two stacks (the lowercase letters are any type
variables of the kinds we have defined so far):
::
- [a A* b .0.] U [c d .1.]
- w/ {c: a}
- [ A* b .0.] U [ d .1.]
+ [a A* b .0.] U [c d .1.]
+ w/ {c: a}
+ [ A* b .0.] U [ d .1.]
Now we have to split universes to unify ``A*``. In the first universe it
disappears:
::
- [b .0.] U [d .1.]
- w/ {d: b, .1.: .0.}
- [] U []
+ [b .0.] U [d .1.]
+ w/ {d: b, .1.: .0.}
+ [] U []
While in the second it spawns an ``A``, which we will label ``e``:
::
- [e A* b .0.] U [d .1.]
- w/ {d: e}
- [ A* b .0.] U [ .1.]
- w/ {.1.: A* b .0.}
- [ A* b .0.] U [ A* b .0.]
+ [e A* b .0.] U [d .1.]
+ w/ {d: e}
+ [ A* b .0.] U [ .1.]
+ w/ {.1.: A* b .0.}
+ [ A* b .0.] U [ A* b .0.]
Giving us two unifiers:
::
- {c: a, d: b, .1.: .0.}
- {c: a, d: e, .1.: A* b .0.}
+ {c: a, d: b, .1.: .0.}
+ {c: a, d: e, .1.: A* b .0.}
.. code:: ipython2
``unify()`` version 4
^^^^^^^^^^^^^^^^^^^^^
-Can now return multiple results...
+Can now return multiple results…
.. code:: ipython2
::
- (a1*, s1) [a1*] (a1, s2) [a1]
+ (a1*, s1) [a1*] (a1, s2) [a1]
- (a1*, (a1, s2)) [a1* a1] (a1, s2) [a1]
+ (a1*, (a1, s2)) [a1* a1] (a1, s2) [a1]
- (a1*, s1) [a1*] (a2, (a1*, s1)) [a2 a1*]
+ (a1*, s1) [a1*] (a2, (a1*, s1)) [a2 a1*]
.. code:: ipython2
In order to compute the stack effect of combinators you kinda have to
have the quoted programs they expect available. In the most general
-case, the ``i`` combinator, you can't say anything about its stack
+case, the ``i`` combinator, you can’t say anything about its stack
effect other than it expects one quote:
::
- i (... [.1.] -- ... .1.)
+ i (... [.1.] -- ... .1.)
Or
::
- i (... [A* .1.] -- ... A*)
+ i (... [A* .1.] -- ... A*)
Consider the type of:
::
- [cons] dip
+ [cons] dip
Obviously it would be:
::
- (a1 [..1] a2 -- [a1 ..1] a2)
+ (a1 [..1] a2 -- [a1 ..1] a2)
``dip`` itself could have:
::
- (a1 [..1] -- ... then what?
+ (a1 [..1] -- ... then what?
-Without any information about the contents of the quote we can't say
+Without any information about the contents of the quote we can’t say
much about the result.
Hybrid Inferencer/Interpreter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-I think there's a way forward. If we convert our list (of terms we are
+I think there’s a way forward. If we convert our list (of terms we are
composing) into a stack structure we can use it as a *Joy expression*,
-then we can treat the *output half* of a function's stack effect comment
+then we can treat the *output half* of a function’s stack effect comment
as a Joy interpreter stack, and just execute combinators directly. We
can hybridize the compostition function with an interpreter to evaluate
combinators, compose non-combinator functions, and put type variables on
the stack. For combinators like ``branch`` that can have more than one
-stack effect we have to "split universes" again and return both.
+stack effect we have to “split universes” again and return both.
Joy Types for Functions
^^^^^^^^^^^^^^^^^^^^^^^
You can also provide an optional stack effect, input-side only, that
will then be used as an identity function (that accepts and returns
-stacks that match the "guard" stack effect) which will be used to guard
+stacks that match the “guard” stack effect) which will be used to guard
against type mismatches going into the evaluation of the combinator.
``infer()``
And that brings us to current Work-In-Progress. The mixed-mode
inferencer/interpreter ``infer()`` function seems to work well. There
are details I should document, and the rest of the code in the ``types``
-module (FIXME link to its docs here!) should be explained... There is
+module (FIXME link to its docs here!) should be explained… There is
cruft to convert the definitions in ``DEFS`` to the new
``SymbolJoyType`` objects, and some combinators. Here is an example of
output from the current code :
The numbers at the start of the lines are the current depth of the
-Python call stack. They're followed by the current computed stack effect
+Python call stack. They’re followed by the current computed stack effect
(initialized to ``ID``) then the pending expression (the inference of
the stack effect of which is the whole object of the current example.)
::
- 7 (--) ∘ [pred] [mul] [div] [nullary bool] dipd branch
- 8 (-- [pred ...2]) ∘ [mul] [div] [nullary bool] dipd branch
- 9 (-- [pred ...2] [mul ...3]) ∘ [div] [nullary bool] dipd branch
- 10 (-- [pred ...2] [mul ...3] [div ...4]) ∘ [nullary bool] dipd branch
- 11 (-- [pred ...2] [mul ...3] [div ...4] [nullary bool ...5]) ∘ dipd branch
- 15 (-- [pred ...5]) ∘ nullary bool [mul] [div] branch
- 19 (-- [pred ...2]) ∘ [stack] dinfrirst bool [mul] [div] branch
- 20 (-- [pred ...2] [stack ]) ∘ dinfrirst bool [mul] [div] branch
- 22 (-- [pred ...2] [stack ]) ∘ dip infra first bool [mul] [div] branch
- 26 (--) ∘ stack [pred] infra first bool [mul] [div] branch
- 29 (... -- ... [...]) ∘ [pred] infra first bool [mul] [div] branch
- 30 (... -- ... [...] [pred ...1]) ∘ infra first bool [mul] [div] branch
- 34 (--) ∘ pred s1 swaack first bool [mul] [div] branch
- 37 (n1 -- n2) ∘ [n1] swaack first bool [mul] [div] branch
- 38 (... n1 -- ... n2 [n1 ...]) ∘ swaack first bool [mul] [div] branch
- 41 (... n1 -- ... n1 [n2 ...]) ∘ first bool [mul] [div] branch
- 44 (n1 -- n1 n2) ∘ bool [mul] [div] branch
- 47 (n1 -- n1 b1) ∘ [mul] [div] branch
- 48 (n1 -- n1 b1 [mul ...1]) ∘ [div] branch
- 49 (n1 -- n1 b1 [mul ...1] [div ...2]) ∘ branch
- 53 (n1 -- n1) ∘ div
- 56 (f2 f1 -- f3) ∘
- 56 (i1 f1 -- f2) ∘
- 56 (f1 i1 -- f2) ∘
- 56 (i2 i1 -- f1) ∘
- 53 (n1 -- n1) ∘ mul
- 56 (f2 f1 -- f3) ∘
- 56 (i1 f1 -- f2) ∘
- 56 (f1 i1 -- f2) ∘
- 56 (i2 i1 -- i3) ∘
- ----------------------------------------
- (f2 f1 -- f3)
- (i1 f1 -- f2)
- (f1 i1 -- f2)
- (i2 i1 -- f1)
- (i2 i1 -- i3)
+ 7 (--) ∘ [pred] [mul] [div] [nullary bool] dipd branch
+ 8 (-- [pred ...2]) ∘ [mul] [div] [nullary bool] dipd branch
+ 9 (-- [pred ...2] [mul ...3]) ∘ [div] [nullary bool] dipd branch
+ 10 (-- [pred ...2] [mul ...3] [div ...4]) ∘ [nullary bool] dipd branch
+ 11 (-- [pred ...2] [mul ...3] [div ...4] [nullary bool ...5]) ∘ dipd branch
+ 15 (-- [pred ...5]) ∘ nullary bool [mul] [div] branch
+ 19 (-- [pred ...2]) ∘ [stack] dinfrirst bool [mul] [div] branch
+ 20 (-- [pred ...2] [stack ]) ∘ dinfrirst bool [mul] [div] branch
+ 22 (-- [pred ...2] [stack ]) ∘ dip infra first bool [mul] [div] branch
+ 26 (--) ∘ stack [pred] infra first bool [mul] [div] branch
+ 29 (... -- ... [...]) ∘ [pred] infra first bool [mul] [div] branch
+ 30 (... -- ... [...] [pred ...1]) ∘ infra first bool [mul] [div] branch
+ 34 (--) ∘ pred s1 swaack first bool [mul] [div] branch
+ 37 (n1 -- n2) ∘ [n1] swaack first bool [mul] [div] branch
+ 38 (... n1 -- ... n2 [n1 ...]) ∘ swaack first bool [mul] [div] branch
+ 41 (... n1 -- ... n1 [n2 ...]) ∘ first bool [mul] [div] branch
+ 44 (n1 -- n1 n2) ∘ bool [mul] [div] branch
+ 47 (n1 -- n1 b1) ∘ [mul] [div] branch
+ 48 (n1 -- n1 b1 [mul ...1]) ∘ [div] branch
+ 49 (n1 -- n1 b1 [mul ...1] [div ...2]) ∘ branch
+ 53 (n1 -- n1) ∘ div
+ 56 (f2 f1 -- f3) ∘
+ 56 (i1 f1 -- f2) ∘
+ 56 (f1 i1 -- f2) ∘
+ 56 (i2 i1 -- f1) ∘
+ 53 (n1 -- n1) ∘ mul
+ 56 (f2 f1 -- f3) ∘
+ 56 (i1 f1 -- f2) ∘
+ 56 (f1 i1 -- f2) ∘
+ 56 (i2 i1 -- i3) ∘
+ ----------------------------------------
+ (f2 f1 -- f3)
+ (i1 f1 -- f2)
+ (f1 i1 -- f2)
+ (i2 i1 -- f1)
+ (i2 i1 -- i3)
Conclusion
----------
-We built a simple type inferencer, and a kind of crude "compiler" for a
+We built a simple type inferencer, and a kind of crude “compiler” for a
subset of Joy functions. Then we built a more powerful inferencer that
actually does some evaluation and explores branching code paths
- the rest of the library has to be covered
- figure out how to deal with ``loop`` and ``genrec``, etc..
- extend the types to check values (see the appendix)
-- other kinds of "higher order" type variables, OR, AND, etc..
+- other kinds of “higher order” type variables, OR, AND, etc..
- maybe rewrite in Prolog for great good?
- definitions
-- don't permit composition of functions that don't compose
-- auto-compile compilable functions
+
+ - don’t permit composition of functions that don’t compose
+ - auto-compile compilable functions
+
- Compiling more than just the Yin functions.
- getting better visibility (than Python debugger.)
- DOOOOCS!!!! Lots of docs!
-- docstrings all around
-- improve this notebook (it kinda falls apart at the end narratively. I
- went off and just started writing code to see if it would work. It
- does, but now I have to come back and describe here what I did.
+
+ - docstrings all around
+ - improve this notebook (it kinda falls apart at the end
+ narratively. I went off and just started writing code to see if it
+ would work. It does, but now I have to come back and describe here
+ what I did.
Appendix: Joy in the Logical Paradigm
-------------------------------------
For *type checking* to work the type label classes have to be modified
to let ``T >= t`` succeed, where e.g. ``T`` is ``IntJoyType`` and ``t``
is ``int``. If you do that you can take advantage of the *logical
-relational* nature of the stack effect comments to "compute in reverse"
-as it were. There's a working demo of this at the end of the ``types``
-module. But if you're interested in all that you should just use Prolog!
+relational* nature of the stack effect comments to “compute in reverse”
+as it were. There’s a working demo of this at the end of the ``types``
+module. But if you’re interested in all that you should just use Prolog!
Anyhow, type *checking* is a few easy steps away.
Traversing Datastructures with Zippers
======================================
-This notebook is about using the "zipper" with joy datastructures. See
+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
+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.
+it, and rebuild it using the “zipper” technique.
.. code:: ipython2
Trees
-----
-In Joypy there aren't any complex datastructures, just ints, floats,
+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
+(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.
::
- z-down == [] swap uncons swap
- z-up == swons swap shunt
- z-right == [swons] cons dip uncons swap
- z-left == swons [uncons swap] dip swap
+ 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
+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.
``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.
+In Joy we have the ``dip`` and ``infra`` combinators which can “target”
+or “address” any particular item in a Joy tree structure.
.. code:: ipython2
[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
+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
::
- [...] [Q] [dip dip infra dip infra dip infra] Z
- -------------------------------------------------------------
- [...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
-
+ [...] [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.
+The ``Z`` function isn’t hard to make.
.. code:: ipython2
::
- [...] [Q] 'ddididi' Zstr
- -------------------------------------------------------------
- [...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
+ [...] [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.
+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"
+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!
+ [ n [ n [ n n x ...
+ i d i d i d d Bingo!
from notebook_preamble import D, DefinitionWrapper, J, V, define
-On "Two Exercises Found in a Book on Algorithmics"
+On “Two Exercises Found in a Book on Algorithmics”
==================================================
Bird & Meertens
Define ``scan`` in terms of a reduction.
----------------------------------------
- Problem I. The reduction operator ``/`` of APL takes some binary
- operator ``⨁`` on its left and a vector ``x`` of values on its
- right. The meaning of ``⨁/x`` for ``x = [a b ... z]`` is the value
- ``a⨁b⨁...⨁z``. For this to be well-defined in the absence of
- brackets, the operation ``⨁`` has to be associative. Now there is
- another operator ``\`` of APL called ``scan``. Its effect is closely
- related to reduction in that we have:
+ Problem I. The reduction operator ``/`` of APL takes some binary
+ operator ``⨁`` on its left and a vector ``x`` of values on its right.
+ The meaning of ``⨁/x`` for ``x = [a b ... z]`` is the value
+ ``a⨁b⨁...⨁z``. For this to be well-defined in the absence of
+ brackets, the operation ``⨁`` has to be associative. Now there is
+ another operator ``\`` of APL called ``scan``. Its effect is closely
+ related to reduction in that we have:
::
- ⨁\x = [a a⨁b a⨁b⨁c ... a⨁b⨁...⨁z]
+ ⨁\x = [a a⨁b a⨁b⨁c ... a⨁b⨁...⨁z]
- The problem is to find some definition of ``scan`` as a reduction.
- In other words, we have to find some function ``f`` and an operator
- ``⨂`` so that
+..
+
+ The problem is to find some definition of ``scan`` as a reduction. In
+ other words, we have to find some function ``f`` and an operator
+ ``⨂`` so that
::
- ⨁\x = f(a)⨂f(b)⨂...⨂f(z)
+ ⨁\x = f(a)⨂f(b)⨂...⨂f(z)
Designing the Recursive Function
--------------------------------
::
- H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
-
- ... a [G] dupdip [H3] dip F
- ... a G a [H3] dip F
- ... a′ a [H3] dip F
- ... a′ H3 a F
- ... a′ [G] dupdip [H3] dip F a F
- ... a′ G a′ [H3] dip F a F
- ... a″ a′ [H3] dip F a F
- ... a″ H3 a′ F a F
- ... a″ [G] dupdip [H3] dip F a′ F a F
- ... a″ G a″ [H3] dip F a′ F a F
- ... a‴ a″ [H3] dip F a′ F a F
- ... a‴ H3 a″ F a′ F a F
- ... a‴ pop c a″ F a′ F a F
- ... c a″ F a′ F a F
- ... d a′ F a F
- ... d′ a F
- ... d″
+ H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
+
+ ... a [G] dupdip [H3] dip F
+ ... a G a [H3] dip F
+ ... a′ a [H3] dip F
+ ... a′ H3 a F
+ ... a′ [G] dupdip [H3] dip F a F
+ ... a′ G a′ [H3] dip F a F
+ ... a″ a′ [H3] dip F a F
+ ... a″ H3 a′ F a F
+ ... a″ [G] dupdip [H3] dip F a′ F a F
+ ... a″ G a″ [H3] dip F a′ F a F
+ ... a‴ a″ [H3] dip F a′ F a F
+ ... a‴ H3 a″ F a′ F a F
+ ... a‴ pop c a″ F a′ F a F
+ ... c a″ F a′ F a F
+ ... d a′ F a F
+ ... d′ a F
+ ... d″
Initial Definition
~~~~~~~~~~~~~~~~~~
-We're building a list of values so this is an "anamorphism". (An
+We’re building a list of values so this is an “anamorphism”. (An
anamorphism uses ``[]`` for ``c`` and ``swons`` for ``F``.)
::
- scan == [P] [pop []] [[G] dupdip] [dip swons] genrec
+ scan == [P] [pop []] [[G] dupdip] [dip swons] genrec
Convert to ``ifte``:
::
- scan == [P] [pop []] [[G] dupdip [scan] dip swons] ifte
+ scan == [P] [pop []] [[G] dupdip [scan] dip swons] ifte
-On the recursive branch ``[G] dupdip`` doesn't cut it:
+On the recursive branch ``[G] dupdip`` doesn’t cut it:
::
- [1 2 3] [G] dupdip [scan] dip swons
- [1 2 3] G [1 2 3] [scan] dip swons
+ [1 2 3] [G] dupdip [scan] dip swons
+ [1 2 3] G [1 2 3] [scan] dip swons
Use ``first``
~~~~~~~~~~~~~
::
- scan == [P] [pop []] [[G] dupdip first] [dip swons] genrec
+ scan == [P] [pop []] [[G] dupdip first] [dip swons] genrec
- [1 2 3] [G] dupdip first [scan] dip swons
- [1 2 3] G [1 2 3] first [scan] dip swons
- [1 2 3] G 1 [scan] dip swons
+ [1 2 3] [G] dupdip first [scan] dip swons
+ [1 2 3] G [1 2 3] first [scan] dip swons
+ [1 2 3] G 1 [scan] dip swons
``G`` applies ``⨁``
~~~~~~~~~~~~~~~~~~~
::
- [1 2 3] G
- [1 2 3] [⨁] infra
- [1 2 3] [+] infra
- [3 3]
+ [1 2 3] G
+ [1 2 3] [⨁] infra
+ [1 2 3] [+] infra
+ [3 3]
Predicate ``P``
~~~~~~~~~~~~~~~
::
- P == size 1 <=
+ P == size 1 <=
-Let's see what we've got so far:
+Let’s see what we’ve got so far:
::
- scan == [P ] [pop []] [[G] dupdip first] [dip swons] genrec
- scan == [size 1 <=] [pop []] [[[F] infra] dupdip first] [dip swons] genrec
+ scan == [P ] [pop []] [[G] dupdip first] [dip swons] genrec
+ scan == [size 1 <=] [pop []] [[[F] infra] dupdip first] [dip swons] genrec
Handling the Last Term
~~~~~~~~~~~~~~~~~~~~~~
[1 3]
-Hmm... Let's take out the ``pop`` for a sec...
+Hmm… Let’s take out the ``pop`` for a sec…
.. code:: ipython2
That leaves the last item in our list, then it puts an empty list on the
-stack and ``swons``'s the new terms onto that. If we leave out that
-empty list, they will be ``swons``'d onto that list that already has the
-last item.
+stack and ``swons``\ ’s the new terms onto that. If we leave out that
+empty list, they will be ``swons``\ ’d onto that list that already has
+the last item.
.. code:: ipython2
::
- [⨁] scan == [size 1 <=] [] [[[⨁] infra] dupdip first] [dip swons] genrec
+ [⨁] scan == [size 1 <=] [] [[[⨁] infra] dupdip first] [dip swons] genrec
Trivially:
::
- == [size 1 <=] [] [[[⨁] infra] dupdip first] [dip swons] genrec
- == [[[⨁] infra] dupdip first] [size 1 <=] [] roll< [dip swons] genrec
- == [[⨁] infra] [dupdip first] cons [size 1 <=] [] roll< [dip swons] genrec
- == [⨁] [infra] cons [dupdip first] cons [size 1 <=] [] roll< [dip swons] genrec
+ == [size 1 <=] [] [[[⨁] infra] dupdip first] [dip swons] genrec
+ == [[[⨁] infra] dupdip first] [size 1 <=] [] roll< [dip swons] genrec
+ == [[⨁] infra] [dupdip first] cons [size 1 <=] [] roll< [dip swons] genrec
+ == [⨁] [infra] cons [dupdip first] cons [size 1 <=] [] roll< [dip swons] genrec
And so:
::
- scan == [infra] cons [dupdip first] cons [size 1 <=] [] roll< [dip swons] genrec
+ scan == [infra] cons [dupdip first] cons [size 1 <=] [] roll< [dip swons] genrec
.. code:: ipython2
Problem 2.
----------
- Define a line to be a sequence of characters not containing the
- newline character. It is easy to define a function ``Unlines`` that
- converts a non-empty sequence of lines into a sequence of characters
- by inserting newline characters between every two lines.
+ Define a line to be a sequence of characters not containing the
+ newline character. It is easy to define a function ``Unlines`` that
+ converts a non-empty sequence of lines into a sequence of characters
+ by inserting newline characters between every two lines.
- Since ``Unlines`` is injective, the function ``Lines``, which
- converts a sequence of characters into a sequence of lines by
- splitting on newline characters, can be specified as the inverse of
- ``Unlines``.
+ Since ``Unlines`` is injective, the function ``Lines``, which
+ converts a sequence of characters into a sequence of lines by
+ splitting on newline characters, can be specified as the inverse of
+ ``Unlines``.
- The problem, just as in Problem 1. is to find a definition by
- reduction of the function ``Lines``.
+ The problem, just as in Problem 1. is to find a definition by
+ reduction of the function ``Lines``.
::
- Unlines = uncons ['\n' swap + +] step
+ Unlines = uncons ['\n' swap + +] step
.. code:: ipython2
'hello\nworld'
-Again ignoring the actual task let's just derive ``Lines``:
+Again ignoring the actual task let’s just derive ``Lines``:
::
- "abc\nefg\nhij" Lines
- ---------------------------
- ["abc" "efg" "hij"]
+ "abc\nefg\nhij" Lines
+ ---------------------------
+ ["abc" "efg" "hij"]
Instead of ``P == [size 1 <=]`` we want ``["\n" in]``, and for the
base-case of a string with no newlines in it we want to use ``unit``:
::
- Lines == ["\n" in] [unit] [R0] [dip swons] genrec
- Lines == ["\n" in] [unit] [R0 [Lines] dip swons] ifte
+ Lines == ["\n" in] [unit] [R0] [dip swons] genrec
+ Lines == ["\n" in] [unit] [R0 [Lines] dip swons] ifte
Derive ``R0``:
::
- "a \n b" R0 [Lines] dip swons
- "a \n b" split-at-newline swap [Lines] dip swons
- "a " " b" swap [Lines] dip swons
- " b" "a " [Lines] dip swons
- " b" Lines "a " swons
- [" b"] "a " swons
- ["a " " b"]
+ "a \n b" R0 [Lines] dip swons
+ "a \n b" split-at-newline swap [Lines] dip swons
+ "a " " b" swap [Lines] dip swons
+ " b" "a " [Lines] dip swons
+ " b" Lines "a " swons
+ [" b"] "a " swons
+ ["a " " b"]
So:
::
- R0 == split-at-newline swap
+ R0 == split-at-newline swap
- Lines == ["\n" in] [unit] [split-at-newline swap] [dip swons] genrec
+ Lines == ["\n" in] [unit] [split-at-newline swap] [dip swons] genrec
Missing the Point?
------------------
::
- 0 [a b c d] [F] step == 0 [a b] [F] step 0 [c d] [F] step concat
+ 0 [a b c d] [F] step == 0 [a b] [F] step 0 [c d] [F] step concat
-For associative function ``F`` and a "unit" element for that function,
+For associative function ``F`` and a “unit” element for that function,
here represented by ``0``.
-For functions that don't have a "unit" we can fake it (the example is
+For functions that don’t have a “unit” we can fake it (the example is
given of infinity for the ``min(a, b)`` function.) We can also use:
::
- safe_step == [size 1 <=] [] [uncons [F] step] ifte
+ safe_step == [size 1 <=] [] [uncons [F] step] ifte
Or:
::
- safe_step == [pop size 1 <=] [pop] [[uncons] dip step] ifte
+ safe_step == [pop size 1 <=] [pop] [[uncons] dip step] ifte
- [a b c] [F] safe_step
- ---------------------------
- a [b c] [F] step
+ [a b c] [F] safe_step
+ ---------------------------
+ a [b c] [F] step
To limit ``F`` to working on pairs of terms from its domain.
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Overview: module code — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<h1>All modules for which code is available</h1>
-<ul><li><a href="builtins.html">builtins</a></li>
+<ul><li><a href="__builtin__.html">__builtin__</a></li>
<li><a href="joy/joy.html">joy.joy</a></li>
<li><a href="joy/library.html">joy.library</a></li>
<li><a href="joy/parser.html">joy.parser</a></li>
<li><a href="joy/utils/pretty_print.html">joy.utils.pretty_print</a></li>
<li><a href="joy/utils/stack.html">joy.utils.stack</a></li>
<li><a href="joy/utils/types.html">joy.utils.types</a></li>
-<li><a href="past/types/basestring.html">past.types.basestring</a></li>
</ul>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="../notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../notebooks/index.html">Essays about Programming in Joy</a></li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.joy — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
- <script src="../../_static/jquery.js"></script>
- <script src="../../_static/underscore.js"></script>
- <script src="../../_static/doctools.js"></script>
- <script src="../../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<h1>Source code for joy.joy</h1><div class="highlight"><pre>
<span class="sd">match the behaviour of the original version(s) written in C.</span>
<span class="sd">'''</span>
-<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">print_function</span>
-<span class="kn">from</span> <span class="nn">builtins</span> <span class="kn">import</span> <span class="nb">input</span>
-<span class="kn">from</span> <span class="nn">traceback</span> <span class="kn">import</span> <span class="n">print_exc</span><span class="p">,</span> <span class="n">format_exc</span>
-<span class="kn">from</span> <span class="nn">.parser</span> <span class="kn">import</span> <span class="n">text_to_expression</span><span class="p">,</span> <span class="n">ParseError</span><span class="p">,</span> <span class="n">Symbol</span>
-<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="kn">import</span> <span class="n">stack_to_string</span>
+<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">print_function</span>
+<span class="kn">from</span> <span class="nn">builtins</span> <span class="k">import</span> <span class="nb">input</span>
+<span class="kn">from</span> <span class="nn">traceback</span> <span class="k">import</span> <span class="n">print_exc</span><span class="p">,</span> <span class="n">format_exc</span>
+<span class="kn">from</span> <span class="nn">.parser</span> <span class="k">import</span> <span class="n">text_to_expression</span><span class="p">,</span> <span class="n">ParseError</span><span class="p">,</span> <span class="n">Symbol</span>
+<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="k">import</span> <span class="n">stack_to_string</span>
<div class="viewcode-block" id="joy"><a class="viewcode-back" href="../../joy.html#joy.joy.joy">[docs]</a><span class="k">def</span> <span class="nf">joy</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">,</span> <span class="n">viewer</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</pre></div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="../../notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../notebooks/index.html">Essays about Programming in Joy</a></li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../index.html">Documentation overview</a><ul>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.library — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
- <script src="../../_static/jquery.js"></script>
- <script src="../../_static/underscore.js"></script>
- <script src="../../_static/doctools.js"></script>
- <script src="../../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<h1>Source code for joy.library</h1><div class="highlight"><pre>
<span class="sd">returns a dictionary of Joy functions suitable for use with the joy()</span>
<span class="sd">function.</span>
<span class="sd">'''</span>
-<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">print_function</span>
-<span class="kn">from</span> <span class="nn">builtins</span> <span class="kn">import</span> <span class="nb">map</span><span class="p">,</span> <span class="nb">object</span><span class="p">,</span> <span class="nb">range</span><span class="p">,</span> <span class="nb">zip</span>
-<span class="kn">from</span> <span class="nn">logging</span> <span class="kn">import</span> <span class="n">getLogger</span>
+<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">print_function</span>
+<span class="kn">from</span> <span class="nn">builtins</span> <span class="k">import</span> <span class="nb">map</span><span class="p">,</span> <span class="nb">object</span><span class="p">,</span> <span class="nb">range</span><span class="p">,</span> <span class="nb">zip</span>
+<span class="kn">from</span> <span class="nn">logging</span> <span class="k">import</span> <span class="n">getLogger</span>
<span class="n">_log</span> <span class="o">=</span> <span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
<span class="n">_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">'Loading library.'</span><span class="p">)</span>
-<span class="kn">from</span> <span class="nn">inspect</span> <span class="kn">import</span> <span class="n">getdoc</span>
-<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">wraps</span>
-<span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">count</span>
-<span class="kn">from</span> <span class="nn">inspect</span> <span class="kn">import</span> <span class="n">getmembers</span><span class="p">,</span> <span class="n">isfunction</span>
+<span class="kn">from</span> <span class="nn">inspect</span> <span class="k">import</span> <span class="n">getdoc</span>
+<span class="kn">from</span> <span class="nn">functools</span> <span class="k">import</span> <span class="n">wraps</span>
+<span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">count</span>
+<span class="kn">from</span> <span class="nn">inspect</span> <span class="k">import</span> <span class="n">getmembers</span><span class="p">,</span> <span class="n">isfunction</span>
<span class="kn">import</span> <span class="nn">operator</span><span class="o">,</span> <span class="nn">math</span>
-<span class="kn">from</span> <span class="nn">.parser</span> <span class="kn">import</span> <span class="n">text_to_expression</span><span class="p">,</span> <span class="n">Symbol</span>
-<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="kn">import</span> <span class="n">expression_to_string</span><span class="p">,</span> <span class="n">list_to_stack</span><span class="p">,</span> <span class="n">iter_stack</span><span class="p">,</span> <span class="n">pick</span><span class="p">,</span> <span class="n">concat</span>
+<span class="kn">from</span> <span class="nn">.parser</span> <span class="k">import</span> <span class="n">text_to_expression</span><span class="p">,</span> <span class="n">Symbol</span>
+<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="k">import</span> <span class="n">expression_to_string</span><span class="p">,</span> <span class="n">list_to_stack</span><span class="p">,</span> <span class="n">iter_stack</span><span class="p">,</span> <span class="n">pick</span><span class="p">,</span> <span class="n">concat</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="o">.</span><span class="n">major</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span>
- <span class="kn">from</span> <span class="nn">.utils.brutal_hackery</span> <span class="kn">import</span> <span class="n">rename_code_object</span>
+ <span class="kn">from</span> <span class="nn">.utils.brutal_hackery</span> <span class="k">import</span> <span class="n">rename_code_object</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">rename_code_object</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">f</span><span class="p">:</span> <span class="n">f</span>
-<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">generated_library</span> <span class="k">as</span> <span class="n">genlib</span>
-<span class="kn">from</span> <span class="nn">.utils.types</span> <span class="kn">import</span> <span class="p">(</span>
+<span class="kn">from</span> <span class="nn">.utils</span> <span class="k">import</span> <span class="n">generated_library</span> <span class="k">as</span> <span class="n">genlib</span>
+<span class="kn">from</span> <span class="nn">.utils.types</span> <span class="k">import</span> <span class="p">(</span>
<span class="n">compose</span><span class="p">,</span>
<span class="n">ef</span><span class="p">,</span>
<span class="n">stack_effect</span><span class="p">,</span>
<span class="n">Ss</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">StackStarJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">))</span>
+<span class="c1"># "sec": stack effect comment, like in Forth.</span>
<span class="n">sec0</span> <span class="o">=</span> <span class="n">stack_effect</span><span class="p">(</span><span class="n">t1</span><span class="p">)()</span>
<span class="n">sec1</span> <span class="o">=</span> <span class="n">stack_effect</span><span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="n">i1</span><span class="p">)(</span><span class="n">s1</span><span class="p">)</span>
<span class="n">sec2</span> <span class="o">=</span> <span class="n">stack_effect</span><span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="n">i1</span><span class="p">)(</span><span class="n">a1</span><span class="p">)</span>
<span class="n">sec_unary_math</span> <span class="o">=</span> <span class="n">stack_effect</span><span class="p">(</span><span class="n">n1</span><span class="p">)(</span><span class="n">n2</span><span class="p">)</span>
<span class="n">sec_Ns_math</span> <span class="o">=</span> <span class="n">stack_effect</span><span class="p">((</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">s1</span><span class="p">),)(</span><span class="n">n0</span><span class="p">)</span>
+<span class="c1"># This is the main dict we're building.</span>
<span class="n">_dictionary</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">definitions</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
-<span class="s1">? == dup truthy</span>
-<span class="s1">*fraction == [uncons] dip uncons [swap] dip concat [*] infra [*] dip cons</span>
-<span class="s1">*fraction0 == concat [[swap] dip * [*] dip] infra</span>
-<span class="s1">anamorphism == [pop []] swap [dip swons] genrec</span>
-<span class="s1">average == [sum 1.0 *] [size] cleave /</span>
-<span class="s1">binary == nullary [popop] dip</span>
-<span class="s1">cleave == fork [popd] dip</span>
-<span class="s1">codireco == cons dip rest cons</span>
-<span class="s1">dinfrirst == dip infra first</span>
-<span class="s1">unstack == ? [uncons ?] loop pop</span>
-<span class="s1">down_to_zero == [0 >] [dup --] while</span>
-<span class="s1">dupdipd == dup dipd</span>
-<span class="s1">enstacken == stack [clear] dip</span>
-<span class="s1">flatten == [] swap [concat] step</span>
-<span class="s1">fork == [i] app2</span>
-<span class="s1">gcd == 1 [tuck modulus dup 0 >] loop pop</span>
-<span class="s1">ifte == [nullary not] dipd branch</span>
-<span class="s1">ii == [dip] dupdip i</span>
-<span class="s1">least_fraction == dup [gcd] infra [div] concat map</span>
-<span class="s1">make_generator == [codireco] ccons</span>
-<span class="s1">nullary == [stack] dinfrirst</span>
-<span class="s1">of == swap at</span>
-<span class="s1">pam == [i] map</span>
-<span class="s1">tailrec == [i] genrec</span>
-<span class="s1">product == 1 swap [*] step</span>
-<span class="s1">quoted == [unit] dip</span>
-<span class="s1">range == [0 <=] [1 - dup] anamorphism</span>
-<span class="s1">range_to_zero == unit [down_to_zero] infra</span>
-<span class="s1">run == [] swap infra</span>
-<span class="s1">size == 0 swap [pop ++] step</span>
-<span class="s1">sqr == dup mul</span>
-<span class="s1">step_zero == 0 roll> step</span>
-<span class="s1">swoncat == swap concat</span>
-<span class="s1">ternary == unary [popop] dip</span>
-<span class="s1">unary == nullary popd</span>
-<span class="s1">unquoted == [i] dip</span>
-<span class="s1">while == swap [nullary] cons dup dipd concat loop</span>
+<span class="s1">? dup truthy</span>
+<span class="s1">*fraction [uncons] dip uncons [swap] dip concat [*] infra [*] dip cons</span>
+<span class="s1">*fraction0 concat [[swap] dip * [*] dip] infra</span>
+<span class="s1">anamorphism [pop []] swap [dip swons] genrec</span>
+<span class="s1">average [sum 1.0 *] [size] cleave /</span>
+<span class="s1">binary nullary [popop] dip</span>
+<span class="s1">cleave fork [popd] dip</span>
+<span class="s1">codireco cons dip rest cons</span>
+<span class="s1">dinfrirst dip infra first</span>
+<span class="s1">unstack ? [uncons ?] loop pop</span>
+<span class="s1">down_to_zero [0 >] [dup --] while</span>
+<span class="s1">dupdipd dup dipd</span>
+<span class="s1">enstacken stack [clear] dip</span>
+<span class="s1">flatten [] swap [concat] step</span>
+<span class="s1">fork [i] app2</span>
+<span class="s1">gcd 1 [tuck modulus dup 0 >] loop pop</span>
+<span class="s1">ifte [nullary not] dipd branch</span>
+<span class="s1">ii [dip] dupdip i</span>
+<span class="s1">least_fraction dup [gcd] infra [div] concat map</span>
+<span class="s1">make_generator [codireco] ccons</span>
+<span class="s1">nullary [stack] dinfrirst</span>
+<span class="s1">of swap at</span>
+<span class="s1">pam [i] map</span>
+<span class="s1">tailrec [i] genrec</span>
+<span class="s1">product 1 swap [*] step</span>
+<span class="s1">quoted [unit] dip</span>
+<span class="s1">range [0 <=] [1 - dup] anamorphism</span>
+<span class="s1">range_to_zero unit [down_to_zero] infra</span>
+<span class="s1">run [] swap infra</span>
+<span class="s1">size 0 swap [pop ++] step</span>
+<span class="s1">sqr dup mul</span>
+<span class="s1">step_zero 0 roll> step</span>
+<span class="s1">swoncat swap concat</span>
+<span class="s1">ternary unary [popop] dip</span>
+<span class="s1">unary nullary popd</span>
+<span class="s1">unquoted [i] dip</span>
+<span class="s1">while swap [nullary] cons dup dipd concat loop</span>
<span class="s1">'''</span>
<span class="c1">#</span>
<span class="c1">#</span>
<span class="sd"> Provide implementation of defined functions, and some helper methods.</span>
<span class="sd"> '''</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">body_text</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">body_text</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">=</span> <span class="n">name</span>
<span class="bp">self</span><span class="o">.</span><span class="n">body</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="n">body_text</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_body</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">iter_stack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> <span class="n">doc</span> <span class="ow">or</span> <span class="n">body_text</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_compiled</span> <span class="o">=</span> <span class="kc">None</span>
- <span class="k">def</span> <span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_compiled</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_compiled</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">)</span> <span class="c1"># pylint: disable=E1102</span>
<span class="n">expression</span> <span class="o">=</span> <span class="n">list_to_stack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_body</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
<span class="sd"> Given some text describing a Joy function definition parse it and</span>
<span class="sd"> return a DefinitionWrapper.</span>
<span class="sd"> '''</span>
- <span class="n">name</span><span class="p">,</span> <span class="n">proper</span><span class="p">,</span> <span class="n">body_text</span> <span class="o">=</span> <span class="p">(</span><span class="n">n</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">defi</span><span class="o">.</span><span class="n">partition</span><span class="p">(</span><span class="s1">'=='</span><span class="p">))</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="n">proper</span><span class="p">:</span>
- <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'Definition </span><span class="si">%r</span><span class="s1"> failed'</span> <span class="o">%</span> <span class="p">(</span><span class="n">defi</span><span class="p">,))</span>
- <span class="k">return</span> <span class="n">class_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">body_text</span><span class="p">)</span></div>
+ <span class="k">return</span> <span class="n">class_</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">n</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">defi</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span></div>
<div class="viewcode-block" id="DefinitionWrapper.add_definitions"><a class="viewcode-back" href="../../library.html#joy.library.DefinitionWrapper.add_definitions">[docs]</a> <span class="nd">@classmethod</span>
<span class="k">def</span> <span class="nf">add_definitions</span><span class="p">(</span><span class="n">class_</span><span class="p">,</span> <span class="n">defs</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">_text_to_defs</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
- <span class="k">return</span> <span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">text</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span> <span class="k">if</span> <span class="s1">'=='</span> <span class="ow">in</span> <span class="n">line</span><span class="p">)</span>
+ <span class="k">return</span> <span class="p">(</span>
+ <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
+ <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">text</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
+ <span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'#'</span><span class="p">)</span>
+ <span class="p">)</span>
<span class="c1">#</span>
<span class="c1"># could change the word in the dictionary to use different semantics.</span>
<span class="n">S_choice</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'choice'</span><span class="p">)</span>
<span class="n">S_first</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'first'</span><span class="p">)</span>
-<span class="n">S_getitem</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'getitem'</span><span class="p">)</span>
<span class="n">S_genrec</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'genrec'</span><span class="p">)</span>
-<span class="n">S_loop</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'loop'</span><span class="p">)</span>
+<span class="n">S_getitem</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'getitem'</span><span class="p">)</span>
<span class="n">S_i</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'i'</span><span class="p">)</span>
<span class="n">S_ifte</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'ifte'</span><span class="p">)</span>
<span class="n">S_infra</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'infra'</span><span class="p">)</span>
+<span class="n">S_loop</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'loop'</span><span class="p">)</span>
<span class="n">S_pop</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'pop'</span><span class="p">)</span>
+<span class="n">S_primrec</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'primrec'</span><span class="p">)</span>
<span class="n">S_step</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'step'</span><span class="p">)</span>
-<span class="n">S_times</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'times'</span><span class="p">)</span>
<span class="n">S_swaack</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'swaack'</span><span class="p">)</span>
+<span class="n">S_times</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'times'</span><span class="p">)</span>
<div class="viewcode-block" id="i"><a class="viewcode-back" href="../../library.html#joy.library.i">[docs]</a><span class="nd">@inscribe</span>
<span class="sd"> General Recursion Combinator.</span>
<span class="sd"> ::</span>
-<span class="sd"> [if] [then] [rec1] [rec2] genrec</span>
-<span class="sd"> ---------------------------------------------------------------------</span>
-<span class="sd"> [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte</span>
+<span class="sd"> [if] [then] [rec1] [rec2] genrec</span>
+<span class="sd"> ---------------------------------------------------------------------</span>
+<span class="sd"> [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte</span>
<span class="sd"> From "Recursion Theory and Joy" (j05cmp.html) by Manfred von Thun:</span>
<span class="sd"> "The genrec combinator takes four program parameters in addition to</span>
<span class="sd"> ::</span>
<span class="sd"> F == [I] [T] [R1] [R2] genrec</span>
-<span class="sd"> == [I] [T] [R1 [F] R2] ifte</span>
+<span class="sd"> == [I] [T] [R1 [F] R2] ifte</span>
<span class="sd"> Primitive recursive functions are those where R2 == i.</span>
<span class="sd"> ::</span>
<span class="sd"> P == [I] [T] [R] tailrec</span>
-<span class="sd"> == [I] [T] [R [P] i] ifte</span>
-<span class="sd"> == [I] [T] [R P] ifte</span>
+<span class="sd"> == [I] [T] [R [P] i] ifte</span>
+<span class="sd"> == [I] [T] [R P] ifte</span>
<span class="sd"> '''</span>
<span class="p">(</span><span class="n">rec2</span><span class="p">,</span> <span class="p">(</span><span class="n">rec1</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="p">(</span><span class="n">S_infra</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span></div>
+<div class="viewcode-block" id="primrec"><a class="viewcode-back" href="../../library.html#joy.library.primrec">[docs]</a><span class="nd">@inscribe</span>
+<span class="nd">@FunctionWrapper</span>
+<span class="k">def</span> <span class="nf">primrec</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
+ <span class="sd">'''</span>
+<span class="sd"> From the "Overview of the language JOY":</span>
+
+<span class="sd"> > The primrec combinator expects two quoted programs in addition to a</span>
+<span class="sd"> data parameter. For an integer data parameter it works like this: If</span>
+<span class="sd"> the data parameter is zero, then the first quotation has to produce</span>
+<span class="sd"> the value to be returned. If the data parameter is positive then the</span>
+<span class="sd"> second has to combine the data parameter with the result of applying</span>
+<span class="sd"> the function to its predecessor.</span>
+
+<span class="sd"> 5 [1] [*] primrec</span>
+
+<span class="sd"> > Then primrec tests whether the top element on the stack (initially</span>
+<span class="sd"> the 5) is equal to zero. If it is, it pops it off and executes one of</span>
+<span class="sd"> the quotations, the [1] which leaves 1 on the stack as the result.</span>
+<span class="sd"> Otherwise it pushes a decremented copy of the top element and</span>
+<span class="sd"> recurses. On the way back from the recursion it uses the other</span>
+<span class="sd"> quotation, [*], to multiply what is now a factorial on top of the</span>
+<span class="sd"> stack by the second element on the stack.</span>
+
+<span class="sd"> n [Base] [Recur] primrec</span>
+
+<span class="sd"> 0 [Base] [Recur] primrec</span>
+<span class="sd"> ------------------------------</span>
+<span class="sd"> Base</span>
+
+<span class="sd"> n [Base] [Recur] primrec</span>
+<span class="sd"> ------------------------------------------ n > 0</span>
+<span class="sd"> n (n-1) [Base] [Recur] primrec Recur</span>
+
+<span class="sd"> '''</span>
+ <span class="n">recur</span><span class="p">,</span> <span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
+ <span class="k">if</span> <span class="n">n</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">:</span>
+ <span class="n">expression</span> <span class="o">=</span> <span class="n">concat</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
+ <span class="k">else</span><span class="p">:</span>
+ <span class="n">expression</span> <span class="o">=</span> <span class="n">S_primrec</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">recur</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
+ <span class="n">stack</span> <span class="o">=</span> <span class="n">recur</span><span class="p">,</span> <span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
+ <span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span></div>
+
+
<span class="c1">#def cleave(S, expression, dictionary):</span>
<span class="c1"># '''</span>
<span class="c1"># The cleave combinator expects two quotations, and below that an item X.</span>
</pre></div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="../../notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../notebooks/index.html">Essays about Programming in Joy</a></li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../index.html">Documentation overview</a><ul>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.parser — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
- <script src="../../_static/jquery.js"></script>
- <script src="../../_static/underscore.js"></script>
- <script src="../../_static/doctools.js"></script>
- <script src="../../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<h1>Source code for joy.parser</h1><div class="highlight"><pre>
<span class="sd">around square brackets.</span>
<span class="sd">'''</span>
-<span class="kn">from</span> <span class="nn">re</span> <span class="kn">import</span> <span class="n">Scanner</span>
-<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="kn">import</span> <span class="n">list_to_stack</span>
+<span class="kn">from</span> <span class="nn">re</span> <span class="k">import</span> <span class="n">Scanner</span>
+<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="k">import</span> <span class="n">list_to_stack</span>
<span class="c1">#TODO: explain the details of float lits and strings.</span>
-<span class="n">FLOAT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'-?\d+\.\d*'</span>
+<span class="n">FLOAT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'-?\d+\.\d*(e(-|\+)\d+)+'</span>
<span class="n">INT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'-?\d+'</span>
<span class="n">SYMBOL</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'[•\w!@$%^&*()_+<>?|\/;:`~,.=-]+'</span>
<span class="n">BRACKETS</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'\[|\]'</span>
</pre></div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="../../notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../notebooks/index.html">Essays about Programming in Joy</a></li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../index.html">Documentation overview</a><ul>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.utils.pretty_print — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
- <script src="../../../_static/jquery.js"></script>
- <script src="../../../_static/underscore.js"></script>
- <script src="../../../_static/doctools.js"></script>
- <script src="../../../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<h1>Source code for joy.utils.pretty_print</h1><div class="highlight"><pre>
<span class="sd">'''</span>
<span class="c1"># (Kinda clunky and hacky. This should be swapped out in favor of much</span>
<span class="c1"># smarter stuff.)</span>
-<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">print_function</span>
-<span class="kn">from</span> <span class="nn">builtins</span> <span class="kn">import</span> <span class="nb">object</span>
-<span class="kn">from</span> <span class="nn">traceback</span> <span class="kn">import</span> <span class="n">print_exc</span>
-<span class="kn">from</span> <span class="nn">.stack</span> <span class="kn">import</span> <span class="n">expression_to_string</span><span class="p">,</span> <span class="n">stack_to_string</span>
-<span class="kn">from</span> <span class="nn">..joy</span> <span class="kn">import</span> <span class="n">joy</span>
-<span class="kn">from</span> <span class="nn">..library</span> <span class="kn">import</span> <span class="n">inscribe</span><span class="p">,</span> <span class="n">FunctionWrapper</span>
+<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">print_function</span>
+<span class="kn">from</span> <span class="nn">builtins</span> <span class="k">import</span> <span class="nb">object</span>
+<span class="kn">from</span> <span class="nn">traceback</span> <span class="k">import</span> <span class="n">print_exc</span>
+<span class="kn">from</span> <span class="nn">.stack</span> <span class="k">import</span> <span class="n">expression_to_string</span><span class="p">,</span> <span class="n">stack_to_string</span>
+<span class="kn">from</span> <span class="nn">..joy</span> <span class="k">import</span> <span class="n">joy</span>
+<span class="kn">from</span> <span class="nn">..library</span> <span class="k">import</span> <span class="n">inscribe</span><span class="p">,</span> <span class="n">FunctionWrapper</span>
<div class="viewcode-block" id="trace"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.trace">[docs]</a><span class="nd">@inscribe</span>
<span class="sd"> trace.</span>
<span class="sd"> '''</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">history</span> <span class="o">=</span> <span class="p">[]</span>
<div class="viewcode-block" id="TracePrinter.viewer"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.TracePrinter.viewer">[docs]</a> <span class="k">def</span> <span class="nf">viewer</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">):</span>
<span class="sd"> '''</span>
<span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">))</span></div>
- <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">go</span><span class="p">())</span>
<div class="viewcode-block" id="TracePrinter.go"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.TracePrinter.go">[docs]</a> <span class="k">def</span> <span class="nf">go</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</pre></div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../../../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/index.html">Essays about Programming in Joy</a></li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>joy.utils.stack — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
- <script src="../../../_static/jquery.js"></script>
- <script src="../../../_static/underscore.js"></script>
- <script src="../../../_static/doctools.js"></script>
- <script src="../../../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../../../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../../../_static/jquery.js"></script>
+ <script type="text/javascript" src="../../../_static/underscore.js"></script>
+ <script type="text/javascript" src="../../../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<h1>Source code for joy.utils.stack</h1><div class="highlight"><pre>
<span class="sd">There is no "Stack" Python class, instead we use the `cons list`_, a </span>
<span class="sd">venerable two-tuple recursive sequence datastructure, where the</span>
-<span class="sd">empty tuple ``()`` is the empty stack and ``(head, rest)`` gives the recursive</span>
-<span class="sd">form of a stack with one or more items on it::</span>
+<span class="sd">empty tuple ``()`` is the empty stack and ``(head, rest)`` gives the</span>
+<span class="sd">recursive form of a stack with one or more items on it::</span>
<span class="sd"> stack := () | (item, stack)</span>
<span class="sd">'''</span>
-<span class="kn">from</span> <span class="nn">builtins</span> <span class="kn">import</span> <span class="nb">map</span>
+<span class="kn">from</span> <span class="nn">builtins</span> <span class="k">import</span> <span class="nb">map</span>
<div class="viewcode-block" id="list_to_stack"><a class="viewcode-back" href="../../../stack.html#joy.utils.stack.list_to_stack">[docs]</a><span class="k">def</span> <span class="nf">list_to_stack</span><span class="p">(</span><span class="n">el</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="p">()):</span>
<span class="sd">'''Convert a Python list (or other sequence) to a Joy stack::</span>
</pre></div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../../../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../../../notebooks/index.html">Essays about Programming in Joy</a></li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
/* -- page layout ----------------------------------------------------------- */
body {
- font-family: Georgia, serif;
+ font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
font-size: 17px;
background-color: #fff;
color: #000;
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
- font-family: Georgia, serif;
+ font-family: 'Garamond', 'Georgia', serif;
color: #444;
font-size: 24px;
font-weight: normal;
div.sphinxsidebar input {
border: 1px solid #CCC;
- font-family: Georgia, serif;
+ font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
font-size: 1em;
}
width: 50%;
}
-div.sphinxsidebar .badge {
- border-bottom: none;
-}
-
-div.sphinxsidebar .badge:hover {
- border-bottom: none;
-}
-
-/* To address an issue with donation coming after search */
-div.sphinxsidebar h3.donation {
- margin-top: 10px;
-}
-
/* -- body styles ----------------------------------------------------------- */
a {
div.body h4,
div.body h5,
div.body h6 {
- font-family: Georgia, serif;
+ font-family: 'Garamond', 'Georgia', serif;
font-weight: normal;
margin: 30px 0px 10px 0px;
padding: 0;
}
div.admonition p.admonition-title {
- font-family: Georgia, serif;
+ font-family: 'Garamond', 'Georgia', serif;
font-weight: normal;
font-size: 24px;
margin: 0 0 10px 0;
}
pre, tt, code {
- font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+ font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-size: 0.9em;
}
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
-}
-
-
-/* relbar */
-
-.related {
- line-height: 30px;
- width: 100%;
- font-size: 0.9rem;
-}
-
-.related.top {
- border-bottom: 1px solid #EEE;
- margin-bottom: 20px;
-}
-
-.related.bottom {
- border-top: 1px solid #EEE;
-}
-
-.related ul {
- padding: 0;
- margin: 0;
- list-style: none;
-}
-
-.related li {
- display: inline;
-}
-
-nav#rellinks {
- float: right;
-}
-
-nav#rellinks li+li:before {
- content: "|";
-}
-
-nav#breadcrumbs li+li:before {
- content: "\00BB";
-}
-
-/* Hide certain items when printing */
-@media print {
- div.related {
- display: none;
- }
}
\ No newline at end of file
*
* Sphinx stylesheet -- basic theme.
*
- * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
font-size: 1em;
}
-div.sphinxsidebar #searchbox form.search {
- overflow: hidden;
-}
-
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
visibility: hidden;
}
-a.brackets:before,
-span.brackets > a:before{
- content: "[";
-}
-
-a.brackets:after,
-span.brackets > a:after {
- content: "]";
-}
-
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
margin-right: auto;
}
-img.align-default, .figure.align-default {
- display: block;
- margin-left: auto;
- margin-right: auto;
-}
-
.align-left {
text-align: left;
}
text-align: center;
}
-.align-default {
- text-align: center;
-}
-
.align-right {
text-align: right;
}
margin-right: auto;
}
-table.align-default {
- margin-left: auto;
- margin-right: auto;
-}
-
table caption span.caption-number {
font-style: italic;
}
border-bottom: none;
}
-th > p:first-child,
-td > p:first-child {
- margin-top: 0px;
-}
-
-th > p:last-child,
-td > p:last-child {
- margin-bottom: 0px;
-}
-
/* -- figures --------------------------------------------------------------- */
div.figure {
hyphens: manual;
}
-/* -- hlist styles ---------------------------------------------------------- */
-
-table.hlist td {
- vertical-align: top;
-}
-
-
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: upper-roman;
}
-li > p:first-child {
- margin-top: 0px;
-}
-
-li > p:last-child {
- margin-bottom: 0px;
-}
-
-dl.footnote > dt,
-dl.citation > dt {
- float: left;
-}
-
-dl.footnote > dd,
-dl.citation > dd {
- margin-bottom: 0em;
-}
-
-dl.footnote > dd:after,
-dl.citation > dd:after {
- content: "";
- clear: both;
-}
-
-dl.field-list {
- display: grid;
- grid-template-columns: fit-content(30%) auto;
-}
-
-dl.field-list > dt {
- font-weight: bold;
- word-break: break-word;
- padding-left: 0.5em;
- padding-right: 5px;
-}
-
-dl.field-list > dt:after {
- content: ":";
-}
-
-dl.field-list > dd {
- padding-left: 0.5em;
- margin-top: 0em;
- margin-left: 0em;
- margin-bottom: 0em;
-}
-
dl {
margin-bottom: 15px;
}
-dd > p:first-child {
+dd p {
margin-top: 0px;
}
font-style: oblique;
}
-.classifier:before {
- font-style: normal;
- margin: 0.5em;
- content: ":";
-}
-
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
margin-top: 0;
}
-div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */
- user-select: none;
-}
-
div.code-block-caption span.caption-number {
padding: 0.1em 0.3em;
font-style: italic;
*
* Sphinx JavaScript utilities for all documentation.
*
- * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
+ var bbox = span.getBBox();
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
- var bbox = node.parentElement.getBBox();
- rect.x.baseVal.value = bbox.x;
+ rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
+ var parentOfText = node.parentNode.parentNode;
addItems.push({
"parent": node.parentNode,
"target": rect});
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
- if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
- this.initOnKeyListeners();
- }
+
},
/**
},
initOnKeyListeners: function() {
- $(document).keydown(function(event) {
+ $(document).keyup(function(event) {
var activeElementType = document.activeElement.tagName;
// don't navigate when in search box or textarea
- if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
- && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
+ if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') {
switch (event.keyCode) {
case 37: // left
var prevHref = $('link[rel="prev"]').prop('href');
$(document).ready(function() {
Documentation.init();
-});
+});
\ No newline at end of file
var DOCUMENTATION_OPTIONS = {
- URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
+ URL_ROOT: '',
VERSION: '0.3.0',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
- BUILDER: 'html',
FILE_SUFFIX: '.html',
- LINK_SUFFIX: '.html',
HAS_SOURCE: true,
- SOURCELINK_SUFFIX: '.txt',
- NAVIGATION_WITH_KEYS: false
+ SOURCELINK_SUFFIX: '.txt'
};
\ No newline at end of file
-/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */
-!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}k.fn=k.prototype={jquery:f,constructor:k,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=k.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return k.each(this,e)},map:function(n){return this.pushStack(k.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},k.extend=k.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(k.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||k.isPlainObject(n)?n:{},i=!1,a[t]=k.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},k.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t){b(e,{nonce:t&&t.nonce})},each:function(e,t){var n,r=0;if(d(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(p,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(d(Object(e))?k.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(d(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g.apply([],a)},guid:1,support:y}),"function"==typeof Symbol&&(k.fn[Symbol.iterator]=t[Symbol.iterator]),k.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var h=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,k="sizzle"+1*new Date,m=n.document,S=0,r=0,p=ue(),x=ue(),N=ue(),A=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",$=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",F=new RegExp(M+"+","g"),B=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="<a id='"+k+"'></a><select id='"+k+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!==C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!==C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(F," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[S,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===S&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[k]||(a[k]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[S,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[k]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace(B,"$1"));return s[k]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[S,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[k]||(e[k]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===S&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[k]&&(v=Ce(v)),y&&!y[k]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[k]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace(B,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace(B," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=N[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[k]?i.push(a):o.push(a);(a=N(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=S+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t===C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument===C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(S=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(S=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=k.split("").sort(D).join("")===k,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);k.find=h,k.expr=h.selectors,k.expr[":"]=k.expr.pseudos,k.uniqueSort=k.unique=h.uniqueSort,k.text=h.getText,k.isXMLDoc=h.isXML,k.contains=h.contains,k.escapeSelector=h.escape;var T=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&k(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},N=k.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var D=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1<i.call(n,e)!==r}):k.filter(n,e,r)}k.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?k.find.matchesSelector(r,e)?[r]:[]:k.find.matches(e,k.grep(t,function(e){return 1===e.nodeType}))},k.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(k(e).filter(function(){for(t=0;t<r;t++)if(k.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)k.find(e,i[t],n);return 1<r?k.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&N.test(e)?k(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(k.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&k(e);if(!N.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&k.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?k.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(k(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(k.uniqueSort(k.merge(this.get(),k(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),k.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return T(e,"parentNode")},parentsUntil:function(e,t,n){return T(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return T(e,"nextSibling")},prevAll:function(e){return T(e,"previousSibling")},nextUntil:function(e,t,n){return T(e,"nextSibling",n)},prevUntil:function(e,t,n){return T(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return"undefined"!=typeof e.contentDocument?e.contentDocument:(A(e,"template")&&(e=e.content||e),k.merge([],e.childNodes))}},function(r,i){k.fn[r]=function(e,t){var n=k.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=k.filter(t,n)),1<this.length&&(O[r]||k.uniqueSort(n),H.test(r)&&n.reverse()),this.pushStack(n)}});var R=/[^\x20\t\r\n\f]+/g;function M(e){return e}function I(e){throw e}function W(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}k.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},k.each(e.match(R)||[],function(e,t){n[t]=!0}),n):k.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){k.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return k.each(arguments,function(e,t){var n;while(-1<(n=k.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<k.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},k.extend({Deferred:function(e){var o=[["notify","progress",k.Callbacks("memory"),k.Callbacks("memory"),2],["resolve","done",k.Callbacks("once memory"),k.Callbacks("once memory"),0,"resolved"],["reject","fail",k.Callbacks("once memory"),k.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return k.Deferred(function(r){k.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,M,s),l(u,o,I,s)):(u++,t.call(e,l(u,o,M,s),l(u,o,I,s),l(u,o,M,o.notifyWith))):(a!==M&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){k.Deferred.exceptionHook&&k.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==I&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(k.Deferred.getStackHook&&(t.stackTrace=k.Deferred.getStackHook()),C.setTimeout(t))}}return k.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:M,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:M)),o[2][3].add(l(0,e,m(n)?n:I))}).promise()},promise:function(e){return null!=e?k.extend(e,a):a}},s={};return k.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=k.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(W(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)W(i[t],a(t),o.reject);return o.promise()}});var $=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;k.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&$.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},k.readyException=function(e){C.setTimeout(function(){throw e})};var F=k.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),k.ready()}k.fn.ready=function(e){return F.then(e)["catch"](function(e){k.readyException(e)}),this},k.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--k.readyWait:k.isReady)||(k.isReady=!0)!==e&&0<--k.readyWait||F.resolveWith(E,[k])}}),k.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(k.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var _=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)_(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(k(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},z=/^-ms-/,U=/-([a-z])/g;function X(e,t){return t.toUpperCase()}function V(e){return e.replace(z,"ms-").replace(U,X)}var G=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function Y(){this.expando=k.expando+Y.uid++}Y.uid=1,Y.prototype={cache:function(e){var t=e[this.expando];return t||(t={},G(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[V(t)]=n;else for(r in t)i[V(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][V(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(V):(t=V(t))in r?[t]:t.match(R)||[]).length;while(n--)delete r[t[n]]}(void 0===t||k.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!k.isEmptyObject(t)}};var Q=new Y,J=new Y,K=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function ee(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(Z,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:K.test(i)?JSON.parse(i):i)}catch(e){}J.set(e,t,n)}else n=void 0;return n}k.extend({hasData:function(e){return J.hasData(e)||Q.hasData(e)},data:function(e,t,n){return J.access(e,t,n)},removeData:function(e,t){J.remove(e,t)},_data:function(e,t,n){return Q.access(e,t,n)},_removeData:function(e,t){Q.remove(e,t)}}),k.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=J.get(o),1===o.nodeType&&!Q.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=V(r.slice(5)),ee(o,r,i[r]));Q.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){J.set(this,n)}):_(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=J.get(o,n))?t:void 0!==(t=ee(o,n))?t:void 0;this.each(function(){J.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){J.remove(this,e)})}}),k.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Q.get(e,t),n&&(!r||Array.isArray(n)?r=Q.access(e,t,k.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=k.queue(e,t),r=n.length,i=n.shift(),o=k._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){k.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Q.get(e,n)||Q.access(e,n,{empty:k.Callbacks("once memory").add(function(){Q.remove(e,[t+"queue",n])})})}}),k.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?k.queue(this[0],t):void 0===n?this:this.each(function(){var e=k.queue(this,t,n);k._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&k.dequeue(this,t)})},dequeue:function(e){return this.each(function(){k.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=k.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Q.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var te=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ne=new RegExp("^(?:([+-])=|)("+te+")([a-z%]*)$","i"),re=["Top","Right","Bottom","Left"],ie=E.documentElement,oe=function(e){return k.contains(e.ownerDocument,e)},ae={composed:!0};ie.getRootNode&&(oe=function(e){return k.contains(e.ownerDocument,e)||e.getRootNode(ae)===e.ownerDocument});var se=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&oe(e)&&"none"===k.css(e,"display")},ue=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];for(o in i=n.apply(e,r||[]),t)e.style[o]=a[o];return i};function le(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return k.css(e,t,"")},u=s(),l=n&&n[3]||(k.cssNumber[t]?"":"px"),c=e.nodeType&&(k.cssNumber[t]||"px"!==l&&+u)&&ne.exec(k.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)k.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,k.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ce={};function fe(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Q.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&se(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ce[s])||(o=a.body.appendChild(a.createElement(s)),u=k.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ce[s]=u)))):"none"!==n&&(l[c]="none",Q.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}k.fn.extend({show:function(){return fe(this,!0)},hide:function(){return fe(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){se(this)?k(this).show():k(this).hide()})}});var pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Q.set(e[n],"globalEval",!t||Q.get(t[n],"globalEval"))}ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;var me,xe,be=/<|&#?\w+;/;function we(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))k.merge(p,o.nodeType?[o]:o);else if(be.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+k.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;k.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<k.inArray(o,r))i&&i.push(o);else if(l=oe(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}me=E.createDocumentFragment().appendChild(E.createElement("div")),(xe=E.createElement("input")).setAttribute("type","radio"),xe.setAttribute("checked","checked"),xe.setAttribute("name","t"),me.appendChild(xe),y.checkClone=me.cloneNode(!0).cloneNode(!0).lastChild.checked,me.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t<arguments.length;t++)u[t]=arguments[t];if(s.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,s)){a=k.event.handlers.call(this,s,l),t=0;while((i=a[t++])&&!s.isPropagationStopped()){s.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!s.isImmediatePropagationStopped())s.rnamespace&&!1!==o.namespace&&!s.rnamespace.test(o.namespace)||(s.handleObj=o,s.data=o.data,void 0!==(r=((k.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,u))&&!1===(s.result=r)&&(s.preventDefault(),s.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,s),s.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<k(i,this).index(l):k.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(k.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[k.expando]?e:new k.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click",ke),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&De(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Q.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},k.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},k.Event=function(e,t){if(!(this instanceof k.Event))return new k.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?ke:Se,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&k.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[k.expando]=!0},k.Event.prototype={constructor:k.Event,isDefaultPrevented:Se,isPropagationStopped:Se,isImmediatePropagationStopped:Se,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=ke,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=ke,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=ke,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},k.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&Te.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&Ce.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},k.event.addProp),k.each({focus:"focusin",blur:"focusout"},function(e,t){k.event.special[e]={setup:function(){return De(this,e,Ne),!1},trigger:function(){return De(this,e),!0},delegateType:t}}),k.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){k.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||k.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),k.fn.extend({on:function(e,t,n,r){return Ae(this,e,t,n,r)},one:function(e,t,n,r){return Ae(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,k(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Se),this.each(function(){k.event.remove(this,e,n,t)})}});var je=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/<script|<style|<link/i,Le=/checked\s*(?:[^=]|=\s*.checked.)/i,He=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n<r;n++)k.event.add(t,i,l[i][n]);J.hasData(e)&&(s=J.access(e),u=k.extend({},s),J.set(t,u))}}function Ie(n,r,i,o){r=g.apply([],r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&Le.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Ie(t,r,i,o)});if(f&&(t=(e=we(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=k.map(ve(e,"script"),Pe)).length;c<f;c++)u=e,c!==p&&(u=k.clone(u,!0,!0),s&&k.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,k.map(a,Re),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Q.access(u,"globalEval")&&k.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?k._evalUrl&&!u.noModule&&k._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")}):b(u.textContent.replace(He,""),u,l))}return n}function We(e,t,n){for(var r,i=t?k.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||k.cleanData(ve(r)),r.parentNode&&(n&&oe(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}k.extend({htmlPrefilter:function(e){return e.replace(je,"<$1></$2>")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Me(o[r],a[r]);else Me(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=k.event.special,o=0;void 0!==(n=e[o]);o++)if(G(n)){if(t=n[Q.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[Q.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),k.fn.extend({detach:function(e){return We(this,e,!0)},remove:function(e){return We(this,e)},text:function(e){return _(this,function(e){return void 0===e?k.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Ie(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Oe(this,e).appendChild(e)})},prepend:function(){return Ie(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Oe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(k.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return k.clone(this,e,t)})},html:function(e){return _(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!qe.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(k.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Ie(this,arguments,function(e){var t=this.parentNode;k.inArray(this,n)<0&&(k.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),k.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){k.fn[e]=function(e){for(var t,n=[],r=k(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),k(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var $e=new RegExp("^("+te+")(?!px)[a-z%]+$","i"),Fe=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Be=new RegExp(re.join("|"),"i");function _e(e,t,n){var r,i,o,a,s=e.style;return(n=n||Fe(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||oe(e)||(a=k.style(e,t)),!y.pixelBoxStyles()&&$e.test(a)&&Be.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function ze(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(u){s.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",u.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",ie.appendChild(s).appendChild(u);var e=C.getComputedStyle(u);n="1%"!==e.top,a=12===t(e.marginLeft),u.style.right="60%",o=36===t(e.right),r=36===t(e.width),u.style.position="absolute",i=12===t(u.offsetWidth/3),ie.removeChild(s),u=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s=E.createElement("div"),u=E.createElement("div");u.style&&(u.style.backgroundClip="content-box",u.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===u.style.backgroundClip,k.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),a},scrollboxSize:function(){return e(),i}}))}();var Ue=["Webkit","Moz","ms"],Xe=E.createElement("div").style,Ve={};function Ge(e){var t=k.cssProps[e]||Ve[e];return t||(e in Xe?e:Ve[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Ue.length;while(n--)if((e=Ue[n]+t)in Xe)return e}(e)||e)}var Ye=/^(none|table(?!-c[ea]).+)/,Qe=/^--/,Je={position:"absolute",visibility:"hidden",display:"block"},Ke={letterSpacing:"0",fontWeight:"400"};function Ze(e,t,n){var r=ne.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function et(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=k.css(e,n+re[a],!0,i)),r?("content"===n&&(u-=k.css(e,"padding"+re[a],!0,i)),"margin"!==n&&(u-=k.css(e,"border"+re[a]+"Width",!0,i))):(u+=k.css(e,"padding"+re[a],!0,i),"padding"!==n?u+=k.css(e,"border"+re[a]+"Width",!0,i):s+=k.css(e,"border"+re[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function tt(e,t,n){var r=Fe(e),i=(!y.boxSizingReliable()||n)&&"border-box"===k.css(e,"boxSizing",!1,r),o=i,a=_e(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if($e.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||"auto"===a||!parseFloat(a)&&"inline"===k.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===k.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+et(e,t,n||(i?"border":"content"),o,r,a)+"px"}function nt(e,t,n,r,i){return new nt.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=_e(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=V(t),u=Qe.test(t),l=e.style;if(u||(t=Ge(s)),a=k.cssHooks[t]||k.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=ne.exec(n))&&i[1]&&(n=le(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(k.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=V(t);return Qe.test(t)||(t=Ge(s)),(a=k.cssHooks[t]||k.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=_e(e,t,r)),"normal"===i&&t in Ke&&(i=Ke[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],function(e,u){k.cssHooks[u]={get:function(e,t,n){if(t)return!Ye.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?tt(e,u,n):ue(e,Je,function(){return tt(e,u,n)})},set:function(e,t,n){var r,i=Fe(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===k.css(e,"boxSizing",!1,i),s=n?et(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-et(e,u,"border",!1,i)-.5)),s&&(r=ne.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=k.css(e,u)),Ze(0,t,s)}}}),k.cssHooks.marginLeft=ze(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(_e(e,"marginLeft"))||e.getBoundingClientRect().left-ue(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),k.each({margin:"",padding:"",border:"Width"},function(i,o){k.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+re[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(k.cssHooks[i+o].set=Ze)}),k.fn.extend({css:function(e,t){return _(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Fe(e),i=t.length;a<i;a++)o[t[a]]=k.css(e,t[a],!1,r);return o}return void 0!==n?k.style(e,t,n):k.css(e,t)},e,t,1<arguments.length)}}),((k.Tween=nt).prototype={constructor:nt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=nt.propHooks[this.prop];return e&&e.get?e.get(this):nt.propHooks._default.get(this)},run:function(e){var t,n=nt.propHooks[this.prop];return this.options.duration?this.pos=t=k.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):nt.propHooks._default.set(this),this}}).init.prototype=nt.prototype,(nt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||!k.cssHooks[e.prop]&&null==e.elem.style[Ge(e.prop)]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=nt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=nt.prototype.init,k.fx.step={};var rt,it,ot,at,st=/^(?:toggle|show|hide)$/,ut=/queueHooks$/;function lt(){it&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(lt):C.setTimeout(lt,k.fx.interval),k.fx.tick())}function ct(){return C.setTimeout(function(){rt=void 0}),rt=Date.now()}function ft(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=re[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function pt(e,t,n){for(var r,i=(dt.tweeners[t]||[]).concat(dt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function dt(o,e,t){var n,a,r=0,i=dt.prefilters.length,s=k.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=rt||ct(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:k.extend({},e),opts:k.extend(!0,{specialEasing:{},easing:k.easing._default},t),originalProperties:e,originalOptions:t,startTime:rt||ct(),duration:t.duration,tweens:[],createTween:function(e,t){var n=k.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=V(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=k.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=dt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(k._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return k.map(c,pt,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),k.fx.timer(k.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}k.Animation=k.extend(dt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return le(n.elem,e,ne.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(R);for(var n,r=0,i=e.length;r<i;r++)n=e[r],dt.tweeners[n]=dt.tweeners[n]||[],dt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&se(e),v=Q.get(e,"fxshow");for(r in n.queue||(null==(a=k._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,k.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],st.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||k.style(e,r)}if((u=!k.isEmptyObject(t))||!k.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Q.get(e,"display")),"none"===(c=k.css(e,"display"))&&(l?c=l:(fe([e],!0),l=e.style.display||l,c=k.css(e,"display"),fe([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===k.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Q.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&fe([e],!0),p.done(function(){for(r in g||fe([e]),Q.remove(e,"fxshow"),d)k.style(e,r,d[r])})),u=pt(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?dt.prefilters.unshift(e):dt.prefilters.push(e)}}),k.speed=function(e,t,n){var r=e&&"object"==typeof e?k.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return k.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in k.fx.speeds?r.duration=k.fx.speeds[r.duration]:r.duration=k.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&k.dequeue(this,r.queue)},r},k.fn.extend({fadeTo:function(e,t,n,r){return this.filter(se).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=k.isEmptyObject(t),o=k.speed(e,n,r),a=function(){var e=dt(this,k.extend({},t),o);(i||Q.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&!1!==i&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=k.timers,r=Q.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&ut.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||k.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Q.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=k.timers,o=n?n.length:0;for(t.finish=!0,k.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),k.each(["toggle","show","hide"],function(e,r){var i=k.fn[r];k.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(ft(r,!0),e,t,n)}}),k.each({slideDown:ft("show"),slideUp:ft("hide"),slideToggle:ft("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){k.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),k.timers=[],k.fx.tick=function(){var e,t=0,n=k.timers;for(rt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||k.fx.stop(),rt=void 0},k.fx.timer=function(e){k.timers.push(e),k.fx.start()},k.fx.interval=13,k.fx.start=function(){it||(it=!0,lt())},k.fx.stop=function(){it=null},k.fx.speeds={slow:600,fast:200,_default:400},k.fn.delay=function(r,e){return r=k.fx&&k.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},ot=E.createElement("input"),at=E.createElement("select").appendChild(E.createElement("option")),ot.type="checkbox",y.checkOn=""!==ot.value,y.optSelected=at.selected,(ot=E.createElement("input")).value="t",ot.type="radio",y.radioValue="t"===ot.value;var ht,gt=k.expr.attrHandle;k.fn.extend({attr:function(e,t){return _(this,k.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){k.removeAttr(this,e)})}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?ht:void 0)),void 0!==n?null===n?void k.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=k.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(R);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ht={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),function(e,t){var a=gt[t]||k.find.attr;gt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=gt[o],gt[o]=r,r=null!=a(e,t,n)?o:null,gt[o]=i),r}});var vt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;function mt(e){return(e.match(R)||[]).join(" ")}function xt(e){return e.getAttribute&&e.getAttribute("class")||""}function bt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(R)||[]}k.fn.extend({prop:function(e,t){return _(this,k.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[k.propFix[e]||e]})}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=k.find.attr(e,"tabindex");return t?parseInt(t,10):vt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(k.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){k.propFix[this.toLowerCase()]=this}),k.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){k(this).addClass(t.call(this,e,xt(this)))});if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=mt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){k(this).removeClass(t.call(this,e,xt(this)))});if(!arguments.length)return this.attr("class","");if((e=bt(t)).length)while(n=this[u++])if(i=xt(n),r=1===n.nodeType&&" "+mt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=mt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){k(this).toggleClass(i.call(this,e,xt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=k(this),r=bt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=xt(this))&&Q.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Q.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+mt(xt(n))+" ").indexOf(t))return!0;return!1}});var wt=/\r/g;k.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,k(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=k.map(t,function(e){return null==e?"":e+""})),(r=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=k.valHooks[t.type]||k.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(wt,""):null==e?"":e:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:mt(k.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=k(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=k.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<k.inArray(k.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<k.inArray(k(e).val(),t)}},y.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var Tt=/^(?:focusinfocus|focusoutblur)$/,Ct=function(e){e.stopPropagation()};k.extend(k.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!Tt.test(d+k.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[k.expando]?e:new k.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:k.makeArray(t,[e]),c=k.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,Tt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Q.get(o,"events")||{})[e.type]&&Q.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&G(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!G(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),k.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,Ct),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,Ct),k.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each(function(){k.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),y.focusin||k.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){k.event.simulate(r,e.target,k.event.fix(e))};k.event.special[r]={setup:function(){var e=this.ownerDocument||this,t=Q.access(e,r);t||e.addEventListener(n,i,!0),Q.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this,t=Q.access(e,r)-1;t?Q.access(e,r,t):(e.removeEventListener(n,i,!0),Q.remove(e,r))}}});var Et=C.location,kt=Date.now(),St=/\?/;k.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||k.error("Invalid XML: "+e),t};var Nt=/\[\]$/,At=/\r?\n/g,Dt=/^(?:submit|button|image|reset|file)$/i,jt=/^(?:input|select|textarea|keygen)/i;function qt(n,e,r,i){var t;if(Array.isArray(e))k.each(e,function(e,t){r||Nt.test(n)?i(n,t):qt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)qt(n+"["+t+"]",e[t],r,i)}k.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!k.isPlainObject(e))k.each(e,function(){i(this.name,this.value)});else for(n in e)qt(n,e[n],t,i);return r.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&jt.test(this.nodeName)&&!Dt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,function(e){return{name:t.name,value:e.replace(At,"\r\n")}}):{name:t.name,value:n.replace(At,"\r\n")}}).get()}});var Lt=/%20/g,Ht=/#.*$/,Ot=/([?&])_=[^&]*/,Pt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Rt=/^(?:GET|HEAD)$/,Mt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Ft=E.createElement("a");function Bt(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(R)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function _t(t,i,o,a){var s={},u=t===Wt;function l(e){var r;return s[e]=!0,k.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function zt(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&k.extend(!0,e,r),e}Ft.href=Et.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Et.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Et.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,k.ajaxSettings),t):zt(k.ajaxSettings,e)},ajaxPrefilter:Bt(It),ajaxTransport:Bt(Wt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=k.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?k(y):k.event,x=k.Deferred(),b=k.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Pt.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Et.href)+"").replace(Mt,Et.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(R)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Ft.protocol+"//"+Ft.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=k.param(v.data,v.traditional)),_t(It,v,t,T),h)return T;for(i in(g=k.event&&v.global)&&0==k.active++&&k.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Rt.test(v.type),f=v.url.replace(Ht,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Lt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(St.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Ot,"$1"),o=(St.test(f)?"&":"?")+"_="+kt+++o),v.url=f+o),v.ifModified&&(k.lastModified[f]&&T.setRequestHeader("If-Modified-Since",k.lastModified[f]),k.etag[f]&&T.setRequestHeader("If-None-Match",k.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+$t+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=_t(Wt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(k.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(k.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--k.active||k.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],function(e,i){k[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),k.ajax(k.extend({url:e,type:i,dataType:r,data:t,success:n},k.isPlainObject(e)&&e))}}),k._evalUrl=function(e,t){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){k.globalEval(e,t)}})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=k(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){k(this).wrapInner(n.call(this,e))}):this.each(function(){var e=k(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){k(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){k(this).replaceWith(this.childNodes)}),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Ut={0:200,1223:204},Xt=k.ajaxSettings.xhr();y.cors=!!Xt&&"withCredentials"in Xt,y.ajax=Xt=!!Xt,k.ajaxTransport(function(i){var o,a;if(y.cors||Xt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Ut[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),k.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return k.globalEval(e),e}}}),k.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),k.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=k("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=mt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&k.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?k("<div>").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}}),k.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),k.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),k.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||k.guid++,i},k.holdReady=function(e){e?k.readyWait++:k.ready(!0)},k.isArray=Array.isArray,k.parseJSON=JSON.parse,k.nodeName=A,k.isFunction=m,k.isWindow=x,k.camelCase=V,k.type=w,k.now=Date.now,k.isNumeric=function(e){var t=k.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return k});var Qt=C.jQuery,Jt=C.$;return k.noConflict=function(e){return C.$===k&&(C.$=Jt),e&&C.jQuery===k&&(C.jQuery=Qt),k},e||(C.jQuery=C.$=k),k});
+/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=Array.isArray(d)))?(e?(e=!1,f=c&&Array.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e);return!1}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}return!1}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,N,e),g(f,c,O,e)):(f++,j.call(a,g(f,c,N,e),g(f,c,O,e),g(f,c,N,c.notifyWith))):(d!==N&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S),
+a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},U=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function V(){this.expando=r.expando+V.uid++}V.uid=1,V.prototype={cache:function(a){var b=a[this.expando];return b||(b={},U(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){Array.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(L)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var W=new V,X=new V,Y=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Z=/[A-Z]/g;function $(a){return"true"===a||"false"!==a&&("null"===a?null:a===+a+""?+a:Y.test(a)?JSON.parse(a):a)}function _(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Z,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c=$(c)}catch(e){}X.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return X.hasData(a)||W.hasData(a)},data:function(a,b,c){return X.access(a,b,c)},removeData:function(a,b){X.remove(a,b)},_data:function(a,b,c){return W.access(a,b,c)},_removeData:function(a,b){W.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=X.get(f),1===f.nodeType&&!W.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),_(f,d,e[d])));W.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){X.set(this,a)}):T(this,function(b){var c;if(f&&void 0===b){if(c=X.get(f,a),void 0!==c)return c;if(c=_(f,a),void 0!==c)return c}else this.each(function(){X.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=W.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var aa=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,ba=new RegExp("^(?:([+-])=|)("+aa+")([a-z%]*)$","i"),ca=["Top","Right","Bottom","Left"],da=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ea=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function fa(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&ba.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ga={};function ha(a){var b,c=a.ownerDocument,d=a.nodeName,e=ga[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ga[d]=e,e)}function ia(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=W.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&da(d)&&(e[f]=ha(d))):"none"!==c&&(e[f]="none",W.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ia(this,!0)},hide:function(){return ia(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){da(this)?r(this).show():r(this).hide()})}});var ja=/^(?:checkbox|radio)$/i,ka=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c<d;c++)W.set(a[c],"globalEval",!b||W.get(b[c],"globalEval"))}var pa=/<|&#?\w+;/;function qa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(pa.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ka.exec(f)||["",""])[1].toLowerCase(),i=ma[h]||ma._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g,h=[],i=b.delegateCount,j=a.target;if(i&&j.nodeType&&!("click"===a.type&&a.button>=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c<i;c++)d=b[c],e=d.selector+" ",void 0===g[e]&&(g[e]=d.needsContext?r(e,this).index(j)>-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i<b.length&&h.push({elem:j,handlers:b.slice(i)}),h},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==xa()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===xa()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&B(this,"input"))return this.click(),!1},_default:function(a){return B(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?va:wa,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:wa,isPropagationStopped:wa,isImmediatePropagationStopped:wa,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=va,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=va,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=va,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&sa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ta.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return ya(this,a,b,c,d)},one:function(a,b,c,d){return ya(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=wa),this.each(function(){r.event.remove(this,a,c,b)})}});var za=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/<script|<style|<link/i,Ba=/checked\s*(?:[^=]|=\s*.checked.)/i,Ca=/^true\/(.*)/,Da=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}X.hasData(a)&&(h=X.access(a),i=r.extend({},h),X.set(b,i))}}function Ia(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ja.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ja(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,na(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ga),l=0;l<i;l++)j=h[l],la.test(j.type||"")&&!W.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Da,""),k))}return a}function Ka(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(na(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&oa(na(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(za,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d<e;d++)Ia(f[d],g[d]);if(b)if(c)for(f=f||na(a),g=g||na(h),d=0,e=f.length;d<e;d++)Ha(f[d],g[d]);else Ha(a,h);return g=na(h,"script"),g.length>0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(na(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ja(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(na(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var La=/^margin/,Ma=new RegExp("^("+aa+")(?!px)[a-z%]+$","i"),Na=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",ra.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,ra.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Oa(a,b,c){var d,e,f,g,h=a.style;return c=c||Na(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ma.test(g)&&La.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Pa(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Qa=/^(none|table(?!-c[ea]).+)/,Ra=/^--/,Sa={position:"absolute",visibility:"hidden",display:"block"},Ta={letterSpacing:"0",fontWeight:"400"},Ua=["Webkit","Moz","ms"],Va=d.createElement("div").style;function Wa(a){if(a in Va)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ua.length;while(c--)if(a=Ua[c]+b,a in Va)return a}function Xa(a){var b=r.cssProps[a];return b||(b=r.cssProps[a]=Wa(a)||a),b}function Ya(a,b,c){var d=ba.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Za(a,b,c,d,e){var f,g=0;for(f=c===(d?"border":"content")?4:"width"===b?1:0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+ca[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+ca[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+ca[f]+"Width",!0,e))):(g+=r.css(a,"padding"+ca[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+ca[f]+"Width",!0,e)));return g}function $a(a,b,c){var d,e=Na(a),f=Oa(a,b,e),g="border-box"===r.css(a,"boxSizing",!1,e);return Ma.test(f)?f:(d=g&&(o.boxSizingReliable()||f===a.style[b]),"auto"===f&&(f=a["offset"+b[0].toUpperCase()+b.slice(1)]),f=parseFloat(f)||0,f+Za(a,b,c||(g?"border":"content"),d,e)+"px")}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Oa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=Ra.test(b),j=a.style;return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:j[b]:(f=typeof c,"string"===f&&(e=ba.exec(c))&&e[1]&&(c=fa(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(j[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i?j.setProperty(b,c):j[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b),i=Ra.test(b);return i||(b=Xa(h)),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Oa(a,b,d)),"normal"===e&&b in Ta&&(e=Ta[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Qa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?$a(a,b,d):ea(a,Sa,function(){return $a(a,b,d)})},set:function(a,c,d){var e,f=d&&Na(a),g=d&&Za(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=ba.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ya(a,c,g)}}}),r.cssHooks.marginLeft=Pa(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Oa(a,"marginLeft"))||a.getBoundingClientRect().left-ea(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+ca[d]+b]=f[d]||f[d-2]||f[0];return e}},La.test(a)||(r.cssHooks[a+b].set=Ya)}),r.fn.extend({css:function(a,b){return T(this,function(a,b,c){var d,e,f={},g=0;if(Array.isArray(b)){for(d=Na(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&da(a),q=W.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],cb.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=W.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ia([a],!0),j=a.style.display||j,k=r.css(a,"display"),ia([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=W.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ia([a],!0),m.done(function(){p||ia([a]),W.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=hb(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],Array.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=kb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=ab||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(i||h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:ab||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);f<g;f++)if(d=kb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,hb,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j}r.Animation=r.extend(kb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return fa(c.elem,a,ba.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(L);for(var c,d=0,e=a.length;d<e;d++)c=a[d],kb.tweeners[c]=kb.tweeners[c]||[],kb.tweeners[c].unshift(b)},prefilters:[ib],prefilter:function(a,b){b?kb.prefilters.unshift(a):kb.prefilters.push(a)}}),r.speed=function(a,b,c){var d=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off?d.duration=0:"number"!=typeof d.duration&&(d.duration in r.fx.speeds?d.duration=r.fx.speeds[d.duration]:d.duration=r.fx.speeds._default),null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){r.isFunction(d.old)&&d.old.call(this),d.queue&&r.dequeue(this,d.queue)},d},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(da).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=kb(this,r.extend({},a),f);(e||W.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=W.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&db.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=W.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),r.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(ab=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),ab=void 0},r.fx.timer=function(a){r.timers.push(a),r.fx.start()},r.fx.interval=13,r.fx.start=function(){bb||(bb=!0,eb())},r.fx.stop=function(){bb=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var lb,mb=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return T(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),
+null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d<i;d++)if(c=e[d],(c.selected||d===f)&&!c.disabled&&(!c.parentNode.disabled||!B(c.parentNode,"optgroup"))){if(b=r(c).val(),g)return b;h.push(b)}return h},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Tb=[],Ub=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Tb.pop()||r.expando+"_"+ub++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Ub.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ub.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Ub,"$1"+e):b.jsonp!==!1&&(b.url+=(vb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Tb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=C.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=qa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=pb(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length},r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),b=f.ownerDocument,c=b.documentElement,e=b.defaultView,{top:d.top+e.pageYOffset-c.clientTop,left:d.left+e.pageXOffset-c.clientLeft}):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),B(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||ra})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return T(this,function(a,d,e){var f;return r.isWindow(a)?f=a:9===a.nodeType&&(f=a.defaultView),void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Pa(o.pixelPosition,function(a,c){if(c)return c=Oa(a,b),Ma.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return T(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.holdReady=function(a){a?r.readyWait++:r.ready(!0)},r.isArray=Array.isArray,r.parseJSON=JSON.parse,r.nodeName=B,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Vb=a.jQuery,Wb=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Wb),b&&a.jQuery===r&&(a.jQuery=Vb),r},b||(a.jQuery=a.$=r),r});
/*
- * searchtools.js
+ * searchtools.js_t
* ~~~~~~~~~~~~~~~~
*
* Sphinx JavaScript utilities for the full-text search.
*
- * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
+ * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
-if (!Scorer) {
- /**
- * Simple result scoring code.
- */
- var Scorer = {
- // Implement the following function to further tweak the score for each result
- // The function takes a result array [filename, title, anchor, descr, score]
- // and returns the new score.
- /*
- score: function(result) {
- return result[4];
- },
- */
-
- // query matches the full name of an object
- objNameMatch: 11,
- // or matches in the last dotted part of the object name
- objPartialMatch: 6,
- // Additive scores depending on the priority of the object
- objPrio: {0: 15, // used to be importantResults
- 1: 5, // used to be objectResults
- 2: -5}, // used to be unimportantResults
- // Used when the priority is not in the mapping.
- objPrioDefault: 0,
-
- // query found in title
- title: 15,
- partialTitle: 7,
- // query found in terms
- term: 5,
- partialTerm: 2
+
+/* Non-minified version JS is _stemmer.js if file is provided */
+/**
+ * Porter Stemmer
+ */
+var Stemmer = function() {
+
+ var step2list = {
+ ational: 'ate',
+ tional: 'tion',
+ enci: 'ence',
+ anci: 'ance',
+ izer: 'ize',
+ bli: 'ble',
+ alli: 'al',
+ entli: 'ent',
+ eli: 'e',
+ ousli: 'ous',
+ ization: 'ize',
+ ation: 'ate',
+ ator: 'ate',
+ alism: 'al',
+ iveness: 'ive',
+ fulness: 'ful',
+ ousness: 'ous',
+ aliti: 'al',
+ iviti: 'ive',
+ biliti: 'ble',
+ logi: 'log'
};
-}
-if (!splitQuery) {
- function splitQuery(query) {
- return query.split(/\s+/);
+ var step3list = {
+ icate: 'ic',
+ ative: '',
+ alize: 'al',
+ iciti: 'ic',
+ ical: 'ic',
+ ful: '',
+ ness: ''
+ };
+
+ var c = "[^aeiou]"; // consonant
+ var v = "[aeiouy]"; // vowel
+ var C = c + "[^aeiouy]*"; // consonant sequence
+ var V = v + "[aeiou]*"; // vowel sequence
+
+ var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
+ var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
+ var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
+ var s_v = "^(" + C + ")?" + v; // vowel in stem
+
+ this.stemWord = function (w) {
+ var stem;
+ var suffix;
+ var firstch;
+ var origword = w;
+
+ if (w.length < 3)
+ return w;
+
+ var re;
+ var re2;
+ var re3;
+ var re4;
+
+ firstch = w.substr(0,1);
+ if (firstch == "y")
+ w = firstch.toUpperCase() + w.substr(1);
+
+ // Step 1a
+ re = /^(.+?)(ss|i)es$/;
+ re2 = /^(.+?)([^s])s$/;
+
+ if (re.test(w))
+ w = w.replace(re,"$1$2");
+ else if (re2.test(w))
+ w = w.replace(re2,"$1$2");
+
+ // Step 1b
+ re = /^(.+?)eed$/;
+ re2 = /^(.+?)(ed|ing)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ re = new RegExp(mgr0);
+ if (re.test(fp[1])) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1];
+ re2 = new RegExp(s_v);
+ if (re2.test(stem)) {
+ w = stem;
+ re2 = /(at|bl|iz)$/;
+ re3 = new RegExp("([^aeiouylsz])\\1$");
+ re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re2.test(w))
+ w = w + "e";
+ else if (re3.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+ else if (re4.test(w))
+ w = w + "e";
+ }
+ }
+
+ // Step 1c
+ re = /^(.+?)y$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(s_v);
+ if (re.test(stem))
+ w = stem + "i";
+ }
+
+ // Step 2
+ re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step2list[suffix];
+ }
+
+ // Step 3
+ re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ suffix = fp[2];
+ re = new RegExp(mgr0);
+ if (re.test(stem))
+ w = stem + step3list[suffix];
+ }
+
+ // Step 4
+ re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
+ re2 = /^(.+?)(s|t)(ion)$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ if (re.test(stem))
+ w = stem;
+ }
+ else if (re2.test(w)) {
+ var fp = re2.exec(w);
+ stem = fp[1] + fp[2];
+ re2 = new RegExp(mgr1);
+ if (re2.test(stem))
+ w = stem;
+ }
+
+ // Step 5
+ re = /^(.+?)e$/;
+ if (re.test(w)) {
+ var fp = re.exec(w);
+ stem = fp[1];
+ re = new RegExp(mgr1);
+ re2 = new RegExp(meq1);
+ re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
+ if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
+ w = stem;
+ }
+ re = /ll$/;
+ re2 = new RegExp(mgr1);
+ if (re.test(w) && re2.test(w)) {
+ re = /.$/;
+ w = w.replace(re,"");
+ }
+
+ // and turn initial Y back to y
+ if (firstch == "y")
+ w = firstch.toLowerCase() + w.substr(1);
+ return w;
}
}
+
+
+/**
+ * Simple result scoring code.
+ */
+var Scorer = {
+ // Implement the following function to further tweak the score for each result
+ // The function takes a result array [filename, title, anchor, descr, score]
+ // and returns the new score.
+ /*
+ score: function(result) {
+ return result[4];
+ },
+ */
+
+ // query matches the full name of an object
+ objNameMatch: 11,
+ // or matches in the last dotted part of the object name
+ objPartialMatch: 6,
+ // Additive scores depending on the priority of the object
+ objPrio: {0: 15, // used to be importantResults
+ 1: 5, // used to be objectResults
+ 2: -5}, // used to be unimportantResults
+ // Used when the priority is not in the mapping.
+ objPrioDefault: 0,
+
+ // query found in title
+ title: 15,
+ // query found in terms
+ term: 5
+};
+
+
+
+
+
+var splitChars = (function() {
+ var result = {};
+ var singles = [96, 180, 187, 191, 215, 247, 749, 885, 903, 907, 909, 930, 1014, 1648,
+ 1748, 1809, 2416, 2473, 2481, 2526, 2601, 2609, 2612, 2615, 2653, 2702,
+ 2706, 2729, 2737, 2740, 2857, 2865, 2868, 2910, 2928, 2948, 2961, 2971,
+ 2973, 3085, 3089, 3113, 3124, 3213, 3217, 3241, 3252, 3295, 3341, 3345,
+ 3369, 3506, 3516, 3633, 3715, 3721, 3736, 3744, 3748, 3750, 3756, 3761,
+ 3781, 3912, 4239, 4347, 4681, 4695, 4697, 4745, 4785, 4799, 4801, 4823,
+ 4881, 5760, 5901, 5997, 6313, 7405, 8024, 8026, 8028, 8030, 8117, 8125,
+ 8133, 8181, 8468, 8485, 8487, 8489, 8494, 8527, 11311, 11359, 11687, 11695,
+ 11703, 11711, 11719, 11727, 11735, 12448, 12539, 43010, 43014, 43019, 43587,
+ 43696, 43713, 64286, 64297, 64311, 64317, 64319, 64322, 64325, 65141];
+ var i, j, start, end;
+ for (i = 0; i < singles.length; i++) {
+ result[singles[i]] = true;
+ }
+ var ranges = [[0, 47], [58, 64], [91, 94], [123, 169], [171, 177], [182, 184], [706, 709],
+ [722, 735], [741, 747], [751, 879], [888, 889], [894, 901], [1154, 1161],
+ [1318, 1328], [1367, 1368], [1370, 1376], [1416, 1487], [1515, 1519], [1523, 1568],
+ [1611, 1631], [1642, 1645], [1750, 1764], [1767, 1773], [1789, 1790], [1792, 1807],
+ [1840, 1868], [1958, 1968], [1970, 1983], [2027, 2035], [2038, 2041], [2043, 2047],
+ [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2307], [2362, 2364], [2366, 2383],
+ [2385, 2391], [2402, 2405], [2419, 2424], [2432, 2436], [2445, 2446], [2449, 2450],
+ [2483, 2485], [2490, 2492], [2494, 2509], [2511, 2523], [2530, 2533], [2546, 2547],
+ [2554, 2564], [2571, 2574], [2577, 2578], [2618, 2648], [2655, 2661], [2672, 2673],
+ [2677, 2692], [2746, 2748], [2750, 2767], [2769, 2783], [2786, 2789], [2800, 2820],
+ [2829, 2830], [2833, 2834], [2874, 2876], [2878, 2907], [2914, 2917], [2930, 2946],
+ [2955, 2957], [2966, 2968], [2976, 2978], [2981, 2983], [2987, 2989], [3002, 3023],
+ [3025, 3045], [3059, 3076], [3130, 3132], [3134, 3159], [3162, 3167], [3170, 3173],
+ [3184, 3191], [3199, 3204], [3258, 3260], [3262, 3293], [3298, 3301], [3312, 3332],
+ [3386, 3388], [3390, 3423], [3426, 3429], [3446, 3449], [3456, 3460], [3479, 3481],
+ [3518, 3519], [3527, 3584], [3636, 3647], [3655, 3663], [3674, 3712], [3717, 3718],
+ [3723, 3724], [3726, 3731], [3752, 3753], [3764, 3772], [3774, 3775], [3783, 3791],
+ [3802, 3803], [3806, 3839], [3841, 3871], [3892, 3903], [3949, 3975], [3980, 4095],
+ [4139, 4158], [4170, 4175], [4182, 4185], [4190, 4192], [4194, 4196], [4199, 4205],
+ [4209, 4212], [4226, 4237], [4250, 4255], [4294, 4303], [4349, 4351], [4686, 4687],
+ [4702, 4703], [4750, 4751], [4790, 4791], [4806, 4807], [4886, 4887], [4955, 4968],
+ [4989, 4991], [5008, 5023], [5109, 5120], [5741, 5742], [5787, 5791], [5867, 5869],
+ [5873, 5887], [5906, 5919], [5938, 5951], [5970, 5983], [6001, 6015], [6068, 6102],
+ [6104, 6107], [6109, 6111], [6122, 6127], [6138, 6159], [6170, 6175], [6264, 6271],
+ [6315, 6319], [6390, 6399], [6429, 6469], [6510, 6511], [6517, 6527], [6572, 6592],
+ [6600, 6607], [6619, 6655], [6679, 6687], [6741, 6783], [6794, 6799], [6810, 6822],
+ [6824, 6916], [6964, 6980], [6988, 6991], [7002, 7042], [7073, 7085], [7098, 7167],
+ [7204, 7231], [7242, 7244], [7294, 7400], [7410, 7423], [7616, 7679], [7958, 7959],
+ [7966, 7967], [8006, 8007], [8014, 8015], [8062, 8063], [8127, 8129], [8141, 8143],
+ [8148, 8149], [8156, 8159], [8173, 8177], [8189, 8303], [8306, 8307], [8314, 8318],
+ [8330, 8335], [8341, 8449], [8451, 8454], [8456, 8457], [8470, 8472], [8478, 8483],
+ [8506, 8507], [8512, 8516], [8522, 8525], [8586, 9311], [9372, 9449], [9472, 10101],
+ [10132, 11263], [11493, 11498], [11503, 11516], [11518, 11519], [11558, 11567],
+ [11622, 11630], [11632, 11647], [11671, 11679], [11743, 11822], [11824, 12292],
+ [12296, 12320], [12330, 12336], [12342, 12343], [12349, 12352], [12439, 12444],
+ [12544, 12548], [12590, 12592], [12687, 12689], [12694, 12703], [12728, 12783],
+ [12800, 12831], [12842, 12880], [12896, 12927], [12938, 12976], [12992, 13311],
+ [19894, 19967], [40908, 40959], [42125, 42191], [42238, 42239], [42509, 42511],
+ [42540, 42559], [42592, 42593], [42607, 42622], [42648, 42655], [42736, 42774],
+ [42784, 42785], [42889, 42890], [42893, 43002], [43043, 43055], [43062, 43071],
+ [43124, 43137], [43188, 43215], [43226, 43249], [43256, 43258], [43260, 43263],
+ [43302, 43311], [43335, 43359], [43389, 43395], [43443, 43470], [43482, 43519],
+ [43561, 43583], [43596, 43599], [43610, 43615], [43639, 43641], [43643, 43647],
+ [43698, 43700], [43703, 43704], [43710, 43711], [43715, 43738], [43742, 43967],
+ [44003, 44015], [44026, 44031], [55204, 55215], [55239, 55242], [55292, 55295],
+ [57344, 63743], [64046, 64047], [64110, 64111], [64218, 64255], [64263, 64274],
+ [64280, 64284], [64434, 64466], [64830, 64847], [64912, 64913], [64968, 65007],
+ [65020, 65135], [65277, 65295], [65306, 65312], [65339, 65344], [65371, 65381],
+ [65471, 65473], [65480, 65481], [65488, 65489], [65496, 65497]];
+ for (i = 0; i < ranges.length; i++) {
+ start = ranges[i][0];
+ end = ranges[i][1];
+ for (j = start; j <= end; j++) {
+ result[j] = true;
+ }
+ }
+ return result;
+})();
+
+function splitQuery(query) {
+ var result = [];
+ var start = -1;
+ for (var i = 0; i < query.length; i++) {
+ if (splitChars[query.charCodeAt(i)]) {
+ if (start !== -1) {
+ result.push(query.slice(start, i));
+ start = -1;
+ }
+ } else if (start === -1) {
+ start = i;
+ }
+ }
+ if (start !== -1) {
+ result.push(query.slice(start));
+ }
+ return result;
+}
+
+
+
+
/**
* Search Module
*/
_queued_query : null,
_pulse_status : -1,
- htmlToText : function(htmlString) {
- var htmlElement = document.createElement('span');
- htmlElement.innerHTML = htmlString;
- $(htmlElement).find('.headerlink').remove();
- docContent = $(htmlElement).find('[role=main]')[0];
- if(docContent === undefined) {
- console.warn("Content block not found. Sphinx search tries to obtain it " +
- "via '[role=main]'. Could you check your theme or template.");
- return "";
- }
- return docContent.textContent || docContent.innerText;
- },
-
init : function() {
var params = $.getQueryParameters();
if (params.q) {
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
- this.status = $('<p class="search-summary"> </p>').appendTo(this.out);
+ this.status = $('<p style="display: none"></p>').appendTo(this.out);
this.output = $('<ul class="search"/>').appendTo(this.out);
$('#search-progress').text(_('Preparing search...'));
*/
query : function(query) {
var i;
+ var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
- var requestUrl = "";
- var linkUrl = "";
- if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
+ if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
} else if (dirname == 'index/') {
dirname = '';
}
- requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;
- linkUrl = requestUrl;
-
+ listItem.append($('<a/>').attr('href',
+ DOCUMENTATION_OPTIONS.URL_ROOT + dirname +
+ highlightstring + item[2]).html(item[1]));
} else {
// normal html builders
- requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;
- linkUrl = item[0] + DOCUMENTATION_OPTIONS.LINK_SUFFIX;
- }
- listItem.append($('<a/>').attr('href',
- linkUrl +
+ listItem.append($('<a/>').attr('href',
+ item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX +
highlightstring + item[2]).html(item[1]));
+ }
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
- $.ajax({url: requestUrl,
+ var suffix = DOCUMENTATION_OPTIONS.SOURCELINK_SUFFIX;
+ if (suffix === undefined) {
+ suffix = '.txt';
+ }
+ $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[5] + (item[5].slice(-suffix.length) === suffix ? '' : suffix),
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
for (var prefix in objects) {
for (var name in objects[prefix]) {
var fullname = (prefix ? prefix + '.' : '') + name;
- var fullnameLower = fullname.toLowerCase()
- if (fullnameLower.indexOf(object) > -1) {
+ if (fullname.toLowerCase().indexOf(object) > -1) {
var score = 0;
- var parts = fullnameLower.split('.');
+ var parts = fullname.split('.');
// check for different match types: exact matches of full name or
// "last name" (i.e. last dotted part)
- if (fullnameLower == object || parts[parts.length - 1] == object) {
+ if (fullname == object || parts[parts.length - 1] == object) {
score += Scorer.objNameMatch;
// matches in last name
} else if (parts[parts.length - 1].indexOf(object) > -1) {
{files: terms[word], score: Scorer.term},
{files: titleterms[word], score: Scorer.title}
];
- // add support for partial matches
- if (word.length > 2) {
- for (var w in terms) {
- if (w.match(word) && !terms[word]) {
- _o.push({files: terms[w], score: Scorer.partialTerm})
- }
- }
- for (var w in titleterms) {
- if (w.match(word) && !titleterms[word]) {
- _o.push({files: titleterms[w], score: Scorer.partialTitle})
- }
- }
- }
// no match but word was a required one
if ($u.every(_o, function(o){return o.files === undefined;})) {
for (j = 0; j < _files.length; j++) {
file = _files[j];
if (!(file in scoreMap))
- scoreMap[file] = {};
+ scoreMap[file] = {}
scoreMap[file][word] = o.score;
}
});
// create the mapping
for (j = 0; j < files.length; j++) {
file = files[j];
- if (file in fileMap && fileMap[file].indexOf(word) === -1)
+ if (file in fileMap)
fileMap[file].push(word);
else
fileMap[file] = [word];
var valid = true;
// check if all requirements are matched
- var filteredTermCount = // as search terms with length < 3 are discarded: ignore
- searchterms.filter(function(term){return term.length > 2}).length
- if (
- fileMap[file].length != searchterms.length &&
- fileMap[file].length != filteredTermCount
- ) continue;
+ if (fileMap[file].length != searchterms.length)
+ continue;
// ensure that none of the excluded terms is in the search result
for (i = 0; i < excluded.length; i++) {
* words. the first one is used to find the occurrence, the
* latter for highlighting it.
*/
- makeSearchSummary : function(htmlText, keywords, hlwords) {
- var text = Search.htmlToText(htmlText);
+ makeSearchSummary : function(text, keywords, hlwords) {
var textLower = text.toLowerCase();
var start = 0;
$.each(keywords, function() {
$(document).ready(function() {
Search.init();
-});
+});
\ No newline at end of file
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Index — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="#" />
<link rel="search" title="Search" href="search.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
</li>
<li><a href="types.html#joy.utils.types.AnyJoyType">AnyJoyType (class in joy.utils.types)</a>
</li>
- <li><a href="types.html#joy.utils.types.AnyStarJoyType">AnyStarJoyType (class in joy.utils.types)</a>
-</li>
<li><a href="library.html#joy.library.app1">app1() (in module joy.library)</a>
</li>
<li><a href="library.html#joy.library.app2">app2() (in module joy.library)</a>
</li>
<li><a href="types.html#joy.utils.types.FloatJoyType">FloatJoyType (class in joy.utils.types)</a>
</li>
- <li><a href="types.html#joy.utils.types.FloatStarJoyType">FloatStarJoyType (class in joy.utils.types)</a>
-</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.library.floor">floor() (in module joy.library)</a>
</li>
<li><a href="types.html#joy.utils.types.IntJoyType">IntJoyType (class in joy.utils.types)</a>
</li>
- <li><a href="types.html#joy.utils.types.IntStarJoyType">IntStarJoyType (class in joy.utils.types)</a>
-</li>
<li><a href="stack.html#joy.utils.stack.iter_stack">iter_stack() (in module joy.utils.stack)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="joy.html#joy.joy.joy">joy() (in module joy.joy)</a>
</li>
- <li>
- joy.joy
-
- <ul>
- <li><a href="joy.html#module-joy.joy">module</a>
+ <li><a href="joy.html#module-joy.joy">joy.joy (module)</a>
</li>
- </ul></li>
- <li>
- joy.library
-
- <ul>
- <li><a href="library.html#module-joy.library">module</a>
+ <li><a href="library.html#module-joy.library">joy.library (module)</a>
</li>
- </ul></li>
- <li>
- joy.parser
-
- <ul>
- <li><a href="parser.html#module-joy.parser">module</a>
+ <li><a href="parser.html#module-joy.parser">joy.parser (module)</a>
</li>
- </ul></li>
- <li>
- joy.utils.generated_library
-
- <ul>
- <li><a href="library.html#module-joy.utils.generated_library">module</a>
-</li>
- </ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
- <li>
- joy.utils.pretty_print
-
- <ul>
- <li><a href="pretty.html#module-joy.utils.pretty_print">module</a>
+ <li><a href="library.html#module-joy.utils.generated_library">joy.utils.generated_library (module)</a>
</li>
- </ul></li>
- <li>
- joy.utils.stack
-
- <ul>
- <li><a href="stack.html#module-joy.utils.stack">module</a>
+ <li><a href="pretty.html#module-joy.utils.pretty_print">joy.utils.pretty_print (module)</a>
</li>
- </ul></li>
- <li>
- joy.utils.types
-
- <ul>
- <li><a href="types.html#module-joy.utils.types">module</a>
+ <li><a href="stack.html#module-joy.utils.stack">joy.utils.stack (module)</a>
+</li>
+ <li><a href="types.html#module-joy.utils.types">joy.utils.types (module)</a>
</li>
- </ul></li>
<li><a href="types.html#joy.utils.types.JoyTypeError">JoyTypeError</a>
</li>
</ul></td>
<h2 id="K">K</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
- <li><a href="types.html#joy.utils.types.AnyStarJoyType.kind">kind (joy.utils.types.AnyStarJoyType attribute)</a>
-
- <ul>
- <li><a href="types.html#joy.utils.types.FloatStarJoyType.kind">(joy.utils.types.FloatStarJoyType attribute)</a>
+ <li><a href="types.html#joy.utils.types.KleeneStar.kind">kind (joy.utils.types.KleeneStar attribute)</a>
</li>
- <li><a href="types.html#joy.utils.types.IntStarJoyType.kind">(joy.utils.types.IntStarJoyType attribute)</a>
-</li>
- <li><a href="types.html#joy.utils.types.KleeneStar.kind">(joy.utils.types.KleeneStar attribute)</a>
-</li>
- <li><a href="types.html#joy.utils.types.NumberStarJoyType.kind">(joy.utils.types.NumberStarJoyType attribute)</a>
-</li>
- <li><a href="types.html#joy.utils.types.StackStarJoyType.kind">(joy.utils.types.StackStarJoyType attribute)</a>
-</li>
- <li><a href="types.html#joy.utils.types.TextStarJoyType.kind">(joy.utils.types.TextStarJoyType attribute)</a>
-</li>
- </ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="types.html#joy.utils.types.KleeneStar">KleeneStar (class in joy.utils.types)</a>
</li>
<li><a href="library.html#joy.library.max_">max_() (in module joy.library)</a>
</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="types.html#joy.utils.types.meta_compose">meta_compose() (in module joy.utils.types)</a>
</li>
<li><a href="library.html#joy.library.min_">min_() (in module joy.library)</a>
</li>
- <li>
- module
-
- <ul>
- <li><a href="joy.html#module-joy.joy">joy.joy</a>
-</li>
- <li><a href="library.html#module-joy.library">joy.library</a>
-</li>
- <li><a href="parser.html#module-joy.parser">joy.parser</a>
-</li>
- <li><a href="library.html#module-joy.utils.generated_library">joy.utils.generated_library</a>
-</li>
- <li><a href="pretty.html#module-joy.utils.pretty_print">joy.utils.pretty_print</a>
-</li>
- <li><a href="stack.html#module-joy.utils.stack">joy.utils.stack</a>
-</li>
- <li><a href="types.html#module-joy.utils.types">joy.utils.types</a>
-</li>
- </ul></li>
</ul></td>
</tr></table>
<li><a href="types.html#joy.utils.types.NumberJoyType">NumberJoyType (class in joy.utils.types)</a>
</li>
</ul></td>
- <td style="width: 33%; vertical-align: top;"><ul>
- <li><a href="types.html#joy.utils.types.NumberStarJoyType">NumberStarJoyType (class in joy.utils.types)</a>
-</li>
- </ul></td>
</tr></table>
<h2 id="O">O</h2>
</li>
<li><a href="types.html#joy.utils.types.poly_compose">poly_compose() (in module joy.utils.types)</a>
</li>
- </ul></td>
- <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.utils.generated_library.pop">pop() (in module joy.utils.generated_library)</a>
</li>
+ </ul></td>
+ <td style="width: 33%; vertical-align: top;"><ul>
<li><a href="library.html#joy.utils.generated_library.popd">popd() (in module joy.utils.generated_library)</a>
</li>
<li><a href="library.html#joy.utils.generated_library.popdd">popdd() (in module joy.utils.generated_library)</a>
</li>
<li><a href="library.html#joy.library.pred">pred() (in module joy.library)</a>
</li>
+ <li><a href="library.html#joy.library.primrec">primrec() (in module joy.library)</a>
+</li>
</ul></td>
</tr></table>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
- <li><a href="types.html#joy.utils.types.StackStarJoyType">StackStarJoyType (class in joy.utils.types)</a>
-</li>
<li><a href="library.html#joy.library.step">step() (in module joy.library)</a>
</li>
<li><a href="library.html#joy.utils.generated_library.stuncons">stuncons() (in module joy.utils.generated_library)</a>
</li>
<li><a href="types.html#joy.utils.types.TextJoyType">TextJoyType (class in joy.utils.types)</a>
</li>
- <li><a href="types.html#joy.utils.types.TextStarJoyType">TextStarJoyType (class in joy.utils.types)</a>
-</li>
<li><a href="library.html#joy.utils.generated_library.third">third() (in module joy.utils.generated_library)</a>
</li>
</ul></td>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thun 0.3.0 Documentation — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Thun: Joy in Python" href="notebooks/Intro.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="thun-release-documentation">
that it works by the “Continuation-Passing Style”.</p>
<p>Joy is:</p>
<ul class="simple">
-<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/Purely_functional_programming">Purely Functional</a></p></li>
-<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/Stack-oriented_programming_language">Stack-based</a></p></li>
-<li><p><a class="reference external" href="https://en.wikipedia.org/wiki/Concatenative_programming_language">Concatinative</a> ( See also <a class="reference external" href="http://www.concatenative.org/wiki/view/Concatenative%20language">concatenative.org</a>)</p></li>
-<li><p><a class="reference internal" href="notebooks/Categorical.html"><span class="doc">Categorical</span></a></p></li>
+<li><a class="reference external" href="https://en.wikipedia.org/wiki/Purely_functional_programming">Purely Functional</a></li>
+<li><a class="reference external" href="https://en.wikipedia.org/wiki/Stack-oriented_programming_language">Stack-based</a></li>
+<li><a class="reference external" href="https://en.wikipedia.org/wiki/Concatenative_programming_language">Concatinative</a> ( See also <a class="reference external" href="http://www.concatenative.org/wiki/view/Concatenative%20language">concatenative.org</a>)</li>
+<li><a class="reference internal" href="notebooks/Categorical.html"><span class="doc">Categorical</span></a></li>
</ul>
<p>I hope that this package is useful in the sense that it provides an
additional joy interpreter (the binary in the archive from La Trobe seems
<div class="section" id="project-hosted-on-osdn">
<h2>Project Hosted on <a class="reference external" href="https://osdn.net/projects/joypy/">OSDN</a><a class="headerlink" href="#project-hosted-on-osdn" title="Permalink to this headline">¶</a></h2>
<ul class="simple">
-<li><p><a class="reference external" href="https://osdn.net/projects/joypy/scm/hg/Joypy/tree/tip/">Source Repository</a> (Mercurial)</p></li>
-<li><p><a class="reference external" href="https://osdn.net/projects/joypy/ticket/">Bug tracker</a></p></li>
-<li><p><a class="reference external" href="https://osdn.net/projects/joypy/forums/">Forums</a></p></li>
-<li><p><a class="reference external" href="https://osdn.net/projects/joypy/lists/">Mailing list</a></p></li>
+<li><a class="reference external" href="https://osdn.net/projects/joypy/scm/hg/Joypy/tree/tip/">Source Repository</a> (Mercurial)</li>
+<li><a class="reference external" href="https://osdn.net/projects/joypy/ticket/">Bug tracker</a></li>
+<li><a class="reference external" href="https://osdn.net/projects/joypy/forums/">Forums</a></li>
+<li><a class="reference external" href="https://osdn.net/projects/joypy/lists/">Mailing list</a></li>
</ul>
</div>
<div class="section" id="information-on-the-joy-language">
<div class="section" id="indices-and-tables">
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1>
<ul class="simple">
-<li><p><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></p></li>
-<li><p><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></p></li>
-<li><p><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></p></li>
+<li><a class="reference internal" href="genindex.html"><span class="std std-ref">Index</span></a></li>
+<li><a class="reference internal" href="py-modindex.html"><span class="std std-ref">Module Index</span></a></li>
+<li><a class="reference internal" href="search.html"><span class="std std-ref">Search Page</span></a></li>
</ul>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="#">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
+ <h3><a href="#">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Thun 0.3.0 Documentation</a><ul>
+<li><a class="reference internal" href="#quick-start">Quick Start</a></li>
+<li><a class="reference internal" href="#project-hosted-on-osdn">Project Hosted on OSDN</a></li>
+<li><a class="reference internal" href="#information-on-the-joy-language">Information on the Joy language</a></li>
+<li><a class="reference internal" href="#documentation-on-thun-dialect">Documentation on Thun Dialect</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="_sources/index.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Joy Interpreter — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Stack or Quote or Sequence or List…" href="stack.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="joy-interpreter">
<p>This module implements an interpreter for a dialect of Joy that
attempts to stay very close to the spirit of Joy but does not precisely
match the behaviour of the original version(s) written in C.</p>
-<dl class="py function">
+<dl class="function">
<dt id="joy.joy.joy">
-<code class="sig-prename descclassname">joy.joy.</code><code class="sig-name descname">joy</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em>, <em class="sig-param"><span class="n">viewer</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#joy"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.joy.joy" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.joy.</code><code class="descname">joy</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em>, <em>viewer=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#joy"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.joy.joy" title="Permalink to this definition">¶</a></dt>
<dd><p>Evaluate a Joy expression on a stack.</p>
<p>This function iterates through a sequence of terms which are either
literals (strings, numbers, sequences of terms) or function symbols.
disctionary and executed.</p>
<p>The viewer is a function that is called with the stack and expression
on every iteration, its return value is ignored.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><ul class="simple">
-<li><p><strong>stack</strong> (<em>stack</em>) – The stack.</p></li>
-<li><p><strong>expression</strong> (<em>stack</em>) – The expression to evaluate.</p></li>
-<li><p><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</p></li>
-<li><p><strong>viewer</strong> (<em>function</em>) – Optional viewer function.</p></li>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>stack</strong> (<em>stack</em>) – The stack.</li>
+<li><strong>expression</strong> (<em>stack</em>) – The expression to evaluate.</li>
+<li><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</li>
+<li><strong>viewer</strong> (<em>function</em>) – Optional viewer function.</li>
</ul>
-</dd>
-<dt class="field-even">Return type</dt>
-<dd class="field-even"><p>(stack, (), dictionary)</p>
-</dd>
-</dl>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">(stack, (), dictionary)</p>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.joy.repl">
-<code class="sig-prename descclassname">joy.joy.</code><code class="sig-name descname">repl</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span><span class="o">=</span><span class="default_value">()</span></em>, <em class="sig-param"><span class="n">dictionary</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#repl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.joy.repl" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.joy.</code><code class="descname">repl</code><span class="sig-paren">(</span><em>stack=()</em>, <em>dictionary=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#repl"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.joy.repl" title="Permalink to this definition">¶</a></dt>
<dd><p>Read-Evaluate-Print Loop</p>
<p>Accept input and run it on the stack, loop.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><ul class="simple">
-<li><p><strong>stack</strong> (<em>stack</em>) – The stack.</p></li>
-<li><p><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</p></li>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>stack</strong> (<em>stack</em>) – The stack.</li>
+<li><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</li>
</ul>
-</dd>
-<dt class="field-even">Return type</dt>
-<dd class="field-even"><p>stack</p>
-</dd>
-</dl>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">stack</p>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.joy.run">
-<code class="sig-prename descclassname">joy.joy.</code><code class="sig-name descname">run</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">text</span></em>, <em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">dictionary</span></em>, <em class="sig-param"><span class="n">viewer</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#run"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.joy.run" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.joy.</code><code class="descname">run</code><span class="sig-paren">(</span><em>text</em>, <em>stack</em>, <em>dictionary</em>, <em>viewer=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/joy.html#run"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.joy.run" title="Permalink to this definition">¶</a></dt>
<dd><p>Return the stack resulting from running the Joy code text on the stack.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><ul class="simple">
-<li><p><strong>text</strong> (<em>str</em>) – Joy code.</p></li>
-<li><p><strong>stack</strong> (<em>stack</em>) – The stack.</p></li>
-<li><p><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</p></li>
-<li><p><strong>viewer</strong> (<em>function</em>) – Optional viewer function.</p></li>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>text</strong> (<em>str</em>) – Joy code.</li>
+<li><strong>stack</strong> (<em>stack</em>) – The stack.</li>
+<li><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</li>
+<li><strong>viewer</strong> (<em>function</em>) – Optional viewer function.</li>
</ul>
-</dd>
-<dt class="field-even">Return type</dt>
-<dd class="field-even"><p>(stack, (), dictionary)</p>
-</dd>
-</dl>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">(stack, (), dictionary)</p>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Joy Interpreter</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#module-joy.joy"><code class="docutils literal notranslate"><span class="pre">joy.joy</span></code></a></li>
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Joy Interpreter</a><ul>
+<li><a class="reference internal" href="#module-joy.joy"><code class="docutils literal notranslate"><span class="pre">joy.joy</span></code></a></li>
</ul>
</li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="_sources/joy.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Functions Grouped by, er, Function with Examples — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Type Inference of Joy Expressions" href="types.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="functions-grouped-by-er-function-with-examples">
<h1>Functions Grouped by, er, Function with Examples<a class="headerlink" href="#functions-grouped-by-er-function-with-examples" title="Permalink to this headline">¶</a></h1>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
</pre></div>
</div>
<div class="section" id="stack-chatter">
it’s “off the shelf” technology.)</p>
<div class="section" id="clear">
<h3><code class="docutils literal notranslate"><span class="pre">clear</span></code><a class="headerlink" href="#clear" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 clear'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 clear'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">nothing</span><span class="p">)</span>
</div>
<div class="section" id="dup-dupd">
<h3><code class="docutils literal notranslate"><span class="pre">dup</span></code> <code class="docutils literal notranslate"><span class="pre">dupd</span></code><a class="headerlink" href="#dup-dupd" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 dup'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 dup'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 dupd'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 dupd'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">2</span> <span class="mi">3</span>
<h3><code class="docutils literal notranslate"><span class="pre">enstacken</span></code> <code class="docutils literal notranslate"><span class="pre">disenstacken</span></code> <code class="docutils literal notranslate"><span class="pre">stack</span></code> <code class="docutils literal notranslate"><span class="pre">unstack</span></code><a class="headerlink" href="#enstacken-disenstacken-stack-unstack" title="Permalink to this headline">¶</a></h3>
<p>(I may have these paired up wrong. I.e. <code class="docutils literal notranslate"><span class="pre">disenstacken</span></code> should be
<code class="docutils literal notranslate"><span class="pre">unstack</span></code> and vice versa.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 enstacken'</span><span class="p">)</span> <span class="c1"># Replace the stack with a quote of itself.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 enstacken'</span><span class="p">)</span> <span class="c1"># Replace the stack with a quote of itself.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'4 5 6 [3 2 1] disenstacken'</span><span class="p">)</span> <span class="c1"># Unpack a list onto the stack.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'4 5 6 [3 2 1] disenstacken'</span><span class="p">)</span> <span class="c1"># Unpack a list onto the stack.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 stack'</span><span class="p">)</span> <span class="c1"># Get the stack on the stack.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 stack'</span><span class="p">)</span> <span class="c1"># Get the stack on the stack.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 [4 5 6] unstack'</span><span class="p">)</span> <span class="c1"># Replace the stack with the list on top.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 [4 5 6] unstack'</span><span class="p">)</span> <span class="c1"># Replace the stack with the list on top.</span>
<span class="c1"># The items appear reversed but they are not,</span>
<span class="c1"># 4 is on the top of both the list and the stack.</span>
</pre></div>
</div>
<div class="section" id="pop-popd-popop">
<h3><code class="docutils literal notranslate"><span class="pre">pop</span></code> <code class="docutils literal notranslate"><span class="pre">popd</span></code> <code class="docutils literal notranslate"><span class="pre">popop</span></code><a class="headerlink" href="#pop-popd-popop" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 popd'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 popd'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 popop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 popop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span>
<h3><code class="docutils literal notranslate"><span class="pre">roll<</span></code> <code class="docutils literal notranslate"><span class="pre">rolldown</span></code> <code class="docutils literal notranslate"><span class="pre">roll></span></code> <code class="docutils literal notranslate"><span class="pre">rollup</span></code><a class="headerlink" href="#roll-rolldown-roll-rollup" title="Permalink to this headline">¶</a></h3>
<p>The “down” and “up” refer to the movement of two of the top three items
(displacing the third.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 roll<'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 roll<'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 roll>'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 roll>'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span>
</div>
<div class="section" id="swap">
<h3><code class="docutils literal notranslate"><span class="pre">swap</span></code><a class="headerlink" href="#swap" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 swap'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 swap'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">3</span> <span class="mi">2</span>
</div>
<div class="section" id="tuck-over">
<h3><code class="docutils literal notranslate"><span class="pre">tuck</span></code> <code class="docutils literal notranslate"><span class="pre">over</span></code><a class="headerlink" href="#tuck-over" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 tuck'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 tuck'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 over'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 over'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">2</span>
</div>
<div class="section" id="unit-quoted-unquoted">
<h3><code class="docutils literal notranslate"><span class="pre">unit</span></code> <code class="docutils literal notranslate"><span class="pre">quoted</span></code> <code class="docutils literal notranslate"><span class="pre">unquoted</span></code><a class="headerlink" href="#unit-quoted-unquoted" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 unit'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 unit'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 quoted'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 quoted'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 [2] 3 unquoted'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 [2] 3 unquoted'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [dup] 3 unquoted'</span><span class="p">)</span> <span class="c1"># Unquoting evaluates. Be aware.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [dup] 3 unquoted'</span><span class="p">)</span> <span class="c1"># Unquoting evaluates. Be aware.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">1</span> <span class="p">[</span><span class="n">dup</span><span class="p">]</span> <span class="mi">3</span> <span class="n">unquoted</span>
<h2>List words<a class="headerlink" href="#list-words" title="Permalink to this headline">¶</a></h2>
<div class="section" id="concat-swoncat-shunt">
<h3><code class="docutils literal notranslate"><span class="pre">concat</span></code> <code class="docutils literal notranslate"><span class="pre">swoncat</span></code> <code class="docutils literal notranslate"><span class="pre">shunt</span></code><a class="headerlink" href="#concat-swoncat-shunt" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [4 5 6] concat'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [4 5 6] concat'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [4 5 6] swoncat'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [4 5 6] swoncat'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [4 5 6] shunt'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [4 5 6] shunt'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">6</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">]</span>
</div>
<div class="section" id="cons-swons-uncons">
<h3><code class="docutils literal notranslate"><span class="pre">cons</span></code> <code class="docutils literal notranslate"><span class="pre">swons</span></code> <code class="docutils literal notranslate"><span class="pre">uncons</span></code><a class="headerlink" href="#cons-swons-uncons" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 [2 3] cons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 [2 3] cons'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[2 3] 1 swons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[2 3] 1 swons'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] uncons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] uncons'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span><span class="p">]</span>
</div>
<div class="section" id="first-second-third-rest">
<h3><code class="docutils literal notranslate"><span class="pre">first</span></code> <code class="docutils literal notranslate"><span class="pre">second</span></code> <code class="docutils literal notranslate"><span class="pre">third</span></code> <code class="docutils literal notranslate"><span class="pre">rest</span></code><a class="headerlink" href="#first-second-third-rest" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] first'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] first'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] second'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] second'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] third'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] third'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] rest'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] rest'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span>
</div>
<div class="section" id="flatten">
<h3><code class="docutils literal notranslate"><span class="pre">flatten</span></code><a class="headerlink" href="#flatten" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[1] [2 [3] 4] [5 6]] flatten'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[1] [2 [3] 4] [5 6]] flatten'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span><span class="p">]</span>
<div class="section" id="getitem-at-of-drop-take">
<h3><code class="docutils literal notranslate"><span class="pre">getitem</span></code> <code class="docutils literal notranslate"><span class="pre">at</span></code> <code class="docutils literal notranslate"><span class="pre">of</span></code> <code class="docutils literal notranslate"><span class="pre">drop</span></code> <code class="docutils literal notranslate"><span class="pre">take</span></code><a class="headerlink" href="#getitem-at-of-drop-take" title="Permalink to this headline">¶</a></h3>
<p><code class="docutils literal notranslate"><span class="pre">at</span></code> and <code class="docutils literal notranslate"><span class="pre">getitem</span></code> are the same function. <code class="docutils literal notranslate"><span class="pre">of</span> <span class="pre">==</span> <span class="pre">swap</span> <span class="pre">at</span></code></p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[10 11 12 13 14] 2 getitem'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[10 11 12 13 14] 2 getitem'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">12</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] 0 at'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] 0 at'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'2 [1 2 3 4] of'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'2 [1 2 3 4] of'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] 2 drop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] 2 drop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">4</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] 2 take'</span><span class="p">)</span> <span class="c1"># reverses the order</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] 2 take'</span><span class="p">)</span> <span class="c1"># reverses the order</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">2</span> <span class="mi">1</span><span class="p">]</span>
</div>
<div class="section" id="remove">
<h3><code class="docutils literal notranslate"><span class="pre">remove</span></code><a class="headerlink" href="#remove" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 1 4] 1 remove'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 1 4] 1 remove'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">4</span><span class="p">]</span>
</div>
<div class="section" id="reverse">
<h3><code class="docutils literal notranslate"><span class="pre">reverse</span></code><a class="headerlink" href="#reverse" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] reverse'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 4] reverse'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">]</span>
</div>
<div class="section" id="size">
<h3><code class="docutils literal notranslate"><span class="pre">size</span></code><a class="headerlink" href="#size" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 1 1 1] size'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 1 1 1] size'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">4</span>
<p>“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.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 [4 5 6] swaack'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 [4 5 6] swaack'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span> <span class="mi">5</span> <span class="mi">4</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">]</span>
</div>
<div class="section" id="choice-select">
<h3><code class="docutils literal notranslate"><span class="pre">choice</span></code> <code class="docutils literal notranslate"><span class="pre">select</span></code><a class="headerlink" href="#choice-select" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 1 choice'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 1 choice'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">9</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 0 choice'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 0 choice'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 9 7] 1 select'</span><span class="p">)</span> <span class="c1"># select is basically getitem, should retire it?</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 9 7] 1 select'</span><span class="p">)</span> <span class="c1"># select is basically getitem, should retire it?</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">9</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 9 7] 0 select'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 9 7] 0 select'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</div>
<div class="section" id="zip">
<h3><code class="docutils literal notranslate"><span class="pre">zip</span></code><a class="headerlink" href="#zip" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [6 5 4] zip'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [6 5 4] zip'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="mi">6</span> <span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [6 5 4] zip [sum] map'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] [6 5 4] zip [sum] map'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">7</span> <span class="mi">7</span> <span class="mi">7</span><span class="p">]</span>
<h2>Math words<a class="headerlink" href="#math-words" title="Permalink to this headline">¶</a></h2>
<div class="section" id="add">
<h3><code class="docutils literal notranslate"><span class="pre">+</span></code> <code class="docutils literal notranslate"><span class="pre">add</span></code><a class="headerlink" href="#add" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 +'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 +'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">32</span>
</div>
<div class="section" id="sub">
<h3><code class="docutils literal notranslate"><span class="pre">-</span></code> <code class="docutils literal notranslate"><span class="pre">sub</span></code><a class="headerlink" href="#sub" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 -'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 -'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">14</span>
</div>
<div class="section" id="mul">
<h3><code class="docutils literal notranslate"><span class="pre">*</span></code> <code class="docutils literal notranslate"><span class="pre">mul</span></code><a class="headerlink" href="#mul" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 *'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 *'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">207</span>
</div>
<div class="section" id="div-floordiv-truediv">
<h3><code class="docutils literal notranslate"><span class="pre">/</span></code> <code class="docutils literal notranslate"><span class="pre">div</span></code> <code class="docutils literal notranslate"><span class="pre">floordiv</span></code> <code class="docutils literal notranslate"><span class="pre">truediv</span></code><a class="headerlink" href="#div-floordiv-truediv" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 /'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 /'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">2.5555555555555554</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 -9 truediv'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 -9 truediv'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mf">2.5555555555555554</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 div'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 div'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 floordiv'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 floordiv'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 -9 div'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 -9 div'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 -9 floordiv'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 -9 floordiv'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mi">3</span>
</div>
<div class="section" id="mod-modulus-rem-remainder">
<h3><code class="docutils literal notranslate"><span class="pre">%</span></code> <code class="docutils literal notranslate"><span class="pre">mod</span></code> <code class="docutils literal notranslate"><span class="pre">modulus</span></code> <code class="docutils literal notranslate"><span class="pre">rem</span></code> <code class="docutils literal notranslate"><span class="pre">remainder</span></code><a class="headerlink" href="#mod-modulus-rem-remainder" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 %'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 %'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">5</span>
</div>
<div class="section" id="neg">
<h3><code class="docutils literal notranslate"><span class="pre">neg</span></code><a class="headerlink" href="#neg" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 neg -5 neg'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 neg -5 neg'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mi">23</span> <span class="mi">5</span>
</div>
<div class="section" id="pow">
<h3><code class="docutils literal notranslate"><span class="pre">pow</span></code><a class="headerlink" href="#pow" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'2 10 pow'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'2 10 pow'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1024</span>
</div>
<div class="section" id="sqr-sqrt">
<h3><code class="docutils literal notranslate"><span class="pre">sqr</span></code> <code class="docutils literal notranslate"><span class="pre">sqrt</span></code><a class="headerlink" href="#sqr-sqrt" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqr'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqr'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">529</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqrt'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqrt'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span>
</div>
<div class="section" id="succ-pred">
<h3><code class="docutils literal notranslate"><span class="pre">++</span></code> <code class="docutils literal notranslate"><span class="pre">succ</span></code> <code class="docutils literal notranslate"><span class="pre">--</span></code> <code class="docutils literal notranslate"><span class="pre">pred</span></code><a class="headerlink" href="#succ-pred" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 ++'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 ++'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 --'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 --'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span>
</div>
<div class="section" id="lshift-rshift">
<h3><code class="docutils literal notranslate"><span class="pre"><<</span></code> <code class="docutils literal notranslate"><span class="pre">lshift</span></code> <code class="docutils literal notranslate"><span class="pre">>></span></code> <code class="docutils literal notranslate"><span class="pre">rshift</span></code><a class="headerlink" href="#lshift-rshift" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'8 1 <<'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'8 1 <<'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">16</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'8 1 >>'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'8 1 >>'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">4</span>
</div>
<div class="section" id="average">
<h3><code class="docutils literal notranslate"><span class="pre">average</span></code><a class="headerlink" href="#average" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 5] average'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 5] average'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">2.75</span>
</div>
<div class="section" id="range-range-to-zero-down-to-zero">
<h3><code class="docutils literal notranslate"><span class="pre">range</span></code> <code class="docutils literal notranslate"><span class="pre">range_to_zero</span></code> <code class="docutils literal notranslate"><span class="pre">down_to_zero</span></code><a class="headerlink" href="#range-range-to-zero-down-to-zero" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range_to_zero'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range_to_zero'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 down_to_zero'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 down_to_zero'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">5</span> <span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span>
</div>
<div class="section" id="product">
<h3><code class="docutils literal notranslate"><span class="pre">product</span></code><a class="headerlink" href="#product" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 5] product'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 5] product'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">30</span>
</div>
<div class="section" id="sum">
<h3><code class="docutils literal notranslate"><span class="pre">sum</span></code><a class="headerlink" href="#sum" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 5] sum'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 5] sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">11</span>
</div>
<div class="section" id="min">
<h3><code class="docutils literal notranslate"><span class="pre">min</span></code><a class="headerlink" href="#min" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 5] min'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3 5] min'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span>
</div>
<div class="section" id="gcd">
<h3><code class="docutils literal notranslate"><span class="pre">gcd</span></code><a class="headerlink" href="#gcd" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'45 30 gcd'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'45 30 gcd'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
<h3><code class="docutils literal notranslate"><span class="pre">least_fraction</span></code><a class="headerlink" href="#least-fraction" title="Permalink to this headline">¶</a></h3>
<p>If we represent fractions as a quoted pair of integers [q d] this word
reduces them to their … least common factors or whatever.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[45 30] least_fraction'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[45 30] least_fraction'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">2</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 12] least_fraction'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 12] least_fraction'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">23</span> <span class="mi">12</span><span class="p">]</span>
<div class="section" id="truthy">
<h3><code class="docutils literal notranslate"><span class="pre">?</span></code> <code class="docutils literal notranslate"><span class="pre">truthy</span></code><a class="headerlink" href="#truthy" title="Permalink to this headline">¶</a></h3>
<p>Get the Boolean value of the item on the top of the stack.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 truthy'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 truthy'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kc">True</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] truthy'</span><span class="p">)</span> <span class="c1"># Python semantics.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] truthy'</span><span class="p">)</span> <span class="c1"># Python semantics.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kc">False</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 truthy'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 truthy'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kc">False</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>? == dup truthy
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'23 ?'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'23 ?'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> . 23 ?
23 True .
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] ?'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] ?'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span> <span class="kc">False</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 ?'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 ?'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span> <span class="kc">False</span>
</div>
<div class="section" id="and">
<h3><code class="docutils literal notranslate"><span class="pre">&</span></code> <code class="docutils literal notranslate"><span class="pre">and</span></code><a class="headerlink" href="#and" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 &'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 &'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span>
</div>
<div class="section" id="ne">
<h3><code class="docutils literal notranslate"><span class="pre">!=</span></code> <code class="docutils literal notranslate"><span class="pre"><></span></code> <code class="docutils literal notranslate"><span class="pre">ne</span></code><a class="headerlink" href="#ne" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 !='</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 9 !='</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kc">True</span>
</div>
<div class="section" id="xor">
<h3><code class="docutils literal notranslate"><span class="pre">^</span></code> <code class="docutils literal notranslate"><span class="pre">xor</span></code><a class="headerlink" href="#xor" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 1 ^'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 1 ^'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 0 ^'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 0 ^'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span>
<h2>Miscellaneous<a class="headerlink" href="#miscellaneous" title="Permalink to this headline">¶</a></h2>
<div class="section" id="help">
<h3><code class="docutils literal notranslate"><span class="pre">help</span></code><a class="headerlink" href="#help" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[help] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[help] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Accepts</span> <span class="n">a</span> <span class="n">quoted</span> <span class="n">symbol</span> <span class="n">on</span> <span class="n">the</span> <span class="n">top</span> <span class="n">of</span> <span class="n">the</span> <span class="n">stack</span> <span class="ow">and</span> <span class="n">prints</span> <span class="n">its</span> <span class="n">docs</span><span class="o">.</span>
</div>
<div class="section" id="parse">
<h3><code class="docutils literal notranslate"><span class="pre">parse</span></code><a class="headerlink" href="#parse" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[parse] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[parse] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Parse</span> <span class="n">the</span> <span class="n">string</span> <span class="n">on</span> <span class="n">the</span> <span class="n">stack</span> <span class="n">to</span> <span class="n">a</span> <span class="n">Joy</span> <span class="n">expression</span><span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 "2 [3] dup" parse'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 "2 [3] dup" parse'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="n">dup</span><span class="p">]</span>
<div class="section" id="run">
<h3><code class="docutils literal notranslate"><span class="pre">run</span></code><a class="headerlink" href="#run" title="Permalink to this headline">¶</a></h3>
<p>Evaluate a quoted Joy sequence.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 dup + +] run'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 dup + +] run'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">5</span><span class="p">]</span>
<h2>Combinators<a class="headerlink" href="#combinators" title="Permalink to this headline">¶</a></h2>
<div class="section" id="app1-app2-app3">
<h3><code class="docutils literal notranslate"><span class="pre">app1</span></code> <code class="docutils literal notranslate"><span class="pre">app2</span></code> <code class="docutils literal notranslate"><span class="pre">app3</span></code><a class="headerlink" href="#app1-app2-app3" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[app1] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[app1] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Given</span> <span class="n">a</span> <span class="n">quoted</span> <span class="n">program</span> <span class="n">on</span> <span class="n">TOS</span> <span class="ow">and</span> <span class="n">anything</span> <span class="k">as</span> <span class="n">the</span> <span class="n">second</span> <span class="n">stack</span> <span class="n">item</span> <span class="n">run</span>
<span class="o">...</span> <span class="p">[</span><span class="n">x</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="o">.</span> <span class="n">infra</span> <span class="n">first</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 4 [sqr *] app1'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 4 [sqr *] app1'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span> <span class="mi">160</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 3 4 [sqr *] app2'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 3 4 [sqr *] app2'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span> <span class="mi">90</span> <span class="mi">160</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[app2] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[app2] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Like</span> <span class="n">app1</span> <span class="k">with</span> <span class="n">two</span> <span class="n">items</span><span class="o">.</span>
<span class="p">[</span><span class="n">x</span> <span class="o">...</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">infra</span> <span class="n">first</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 2 3 4 [sqr *] app3'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 2 3 4 [sqr *] app3'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span> <span class="mi">40</span> <span class="mi">90</span> <span class="mi">160</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">range</span> <span class="o">==</span> <span class="p">[</span><span class="mi">0</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[</span><span class="mi">1</span> <span class="o">-</span> <span class="n">dup</span><span class="p">]</span> <span class="n">anamorphism</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 [0 <=] [1 - dup] anamorphism'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 [0 <=] [1 - dup] anamorphism'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span><span class="p">]</span>
</div>
<div class="section" id="branch">
<h3><code class="docutils literal notranslate"><span class="pre">branch</span></code><a class="headerlink" href="#branch" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 4 1 [+] [*] branch'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 4 1 [+] [*] branch'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">12</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 4 0 [+] [*] branch'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 4 0 [+] [*] branch'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">7</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">cleave</span> <span class="o">==</span> <span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="n">app2</span> <span class="p">[</span><span class="n">popd</span><span class="p">]</span> <span class="n">dip</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 2 [+] [-] cleave'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 2 [+] [-] cleave'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span> <span class="mi">12</span> <span class="mi">8</span>
</div>
<div class="section" id="dip-dipd-dipdd">
<h3><code class="docutils literal notranslate"><span class="pre">dip</span></code> <code class="docutils literal notranslate"><span class="pre">dipd</span></code> <code class="docutils literal notranslate"><span class="pre">dipdd</span></code><a class="headerlink" href="#dip-dipd-dipdd" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] dip'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] dip'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">7</span> <span class="mi">5</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] dipd'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] dipd'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">5</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] dipdd'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] dipdd'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">n</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">dupdip</span> <span class="o">==</span> <span class="n">n</span> <span class="n">Q</span> <span class="n">n</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'23 [++] dupdip *'</span><span class="p">)</span> <span class="c1"># N(N + 1)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'23 [++] dupdip *'</span><span class="p">)</span> <span class="c1"># N(N + 1)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">23</span> <span class="p">[</span><span class="o">++</span><span class="p">]</span> <span class="n">dupdip</span> <span class="o">*</span>
</div>
<div class="section" id="genrec-primrec">
<h3><code class="docutils literal notranslate"><span class="pre">genrec</span></code> <code class="docutils literal notranslate"><span class="pre">primrec</span></code><a class="headerlink" href="#genrec-primrec" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[genrec] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[genrec] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">General</span> <span class="n">Recursion</span> <span class="n">Combinator</span><span class="o">.</span>
<span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 [1 <=] [] [dup --] [i *] genrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 [1 <=] [] [dup --] [i *] genrec'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span>
</div>
<div class="section" id="i">
<h3><code class="docutils literal notranslate"><span class="pre">i</span></code><a class="headerlink" href="#i" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 2 3 [+ +] i'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 2 3 [+ +] i'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="p">[</span><span class="o">+</span> <span class="o">+</span><span class="p">]</span> <span class="n">i</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">predicate</span><span class="p">]</span> <span class="p">[</span><span class="n">then</span><span class="p">]</span> <span class="p">[</span><span class="k">else</span><span class="p">]</span> <span class="n">ifte</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 [1] [+] [*] ifte'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 [1] [+] [*] ifte'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 [0] [+] [*] ifte'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 [0] [+] [*] ifte'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span>
</div>
<div class="section" id="infra">
<h3><code class="docutils literal notranslate"><span class="pre">infra</span></code><a class="headerlink" href="#infra" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 2 3 [4 5 6] [* +] infra'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 2 3 [4 5 6] [* +] infra'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span><span class="p">]</span> <span class="p">[</span><span class="o">*</span> <span class="o">+</span><span class="p">]</span> <span class="n">infra</span>
</div>
<div class="section" id="loop">
<h3><code class="docutils literal notranslate"><span class="pre">loop</span></code><a class="headerlink" href="#loop" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[loop] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[loop] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Basic</span> <span class="n">loop</span> <span class="n">combinator</span><span class="o">.</span>
<span class="o">...</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'3 dup [1 - dup] loop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'3 dup [1 - dup] loop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">3</span> <span class="n">dup</span> <span class="p">[</span><span class="mi">1</span> <span class="o">-</span> <span class="n">dup</span><span class="p">]</span> <span class="n">loop</span>
</div>
<div class="section" id="map-pam">
<h3><code class="docutils literal notranslate"><span class="pre">map</span></code> <code class="docutils literal notranslate"><span class="pre">pam</span></code><a class="headerlink" href="#map-pam" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 [1 2 3] [*] map'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 [1 2 3] [*] map'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span> <span class="p">[</span><span class="mi">10</span> <span class="mi">20</span> <span class="mi">30</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 5 [[*][/][+][-]] pam'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'10 5 [[*][/][+][-]] pam'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span> <span class="mi">5</span> <span class="p">[</span><span class="mi">50</span> <span class="mf">2.0</span> <span class="mi">15</span> <span class="mi">5</span><span class="p">]</span>
<h3><code class="docutils literal notranslate"><span class="pre">nullary</span></code> <code class="docutils literal notranslate"><span class="pre">unary</span></code> <code class="docutils literal notranslate"><span class="pre">binary</span></code> <code class="docutils literal notranslate"><span class="pre">ternary</span></code><a class="headerlink" href="#nullary-unary-binary-ternary" title="Permalink to this headline">¶</a></h3>
<p>Run a quoted program enforcing
<a class="reference external" href="https://en.wikipedia.org/wiki/Arity">arity</a>.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] nullary'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] nullary'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">9</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] unary'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] unary'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">9</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] binary'</span><span class="p">)</span> <span class="c1"># + has arity 2 so this is technically pointless...</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] binary'</span><span class="p">)</span> <span class="c1"># + has arity 2 so this is technically pointless...</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">9</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] ternary'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 2 3 4 5 [+] ternary'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">9</span>
</div>
<div class="section" id="step">
<h3><code class="docutils literal notranslate"><span class="pre">step</span></code><a class="headerlink" href="#step" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[step] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[step] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Run</span> <span class="n">a</span> <span class="n">quoted</span> <span class="n">program</span> <span class="n">on</span> <span class="n">each</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">a</span> <span class="n">sequence</span><span class="o">.</span>
<span class="n">on</span> <span class="n">top</span> <span class="n">of</span> <span class="n">the</span> <span class="n">stack</span><span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 [1 2 3] [+] step'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 [1 2 3] [+] step'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="n">step</span>
</div>
<div class="section" id="times">
<h3><code class="docutils literal notranslate"><span class="pre">times</span></code><a class="headerlink" href="#times" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'3 2 1 2 [+] times'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'3 2 1 2 [+] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">2</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="n">times</span>
</div>
<div class="section" id="b">
<h3><code class="docutils literal notranslate"><span class="pre">b</span></code><a class="headerlink" href="#b" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[b] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[b] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">==</span> <span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="n">dip</span> <span class="n">i</span>
<span class="o">...</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">b</span> <span class="o">==</span> <span class="o">...</span> <span class="n">P</span> <span class="n">Q</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 2 [3] [4] b'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 2 [3] [4] b'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">1</span> <span class="mi">2</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="n">b</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">predicate</span><span class="p">]</span> <span class="p">[</span><span class="n">body</span><span class="p">]</span> <span class="k">while</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 [0 >] [dup --] while'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 [0 >] [dup --] while'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span>
</div>
<div class="section" id="x">
<h3><code class="docutils literal notranslate"><span class="pre">x</span></code><a class="headerlink" href="#x" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[x] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[x] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">==</span> <span class="n">dup</span> <span class="n">i</span>
<span class="o">...</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">x</span> <span class="o">=</span> <span class="o">...</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">Q</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [2] [i 3] x'</span><span class="p">)</span> <span class="c1"># Kind of a pointless example.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [2] [i 3] x'</span><span class="p">)</span> <span class="c1"># Kind of a pointless example.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">1</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="n">i</span> <span class="mi">3</span><span class="p">]</span> <span class="n">x</span>
*arithmetic*</a>
over quote-only datastructures (that is, datastructures that consist
soley of containers, without strings or numbers or anything else.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] void'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] void'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kc">False</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[]] void'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[]] void'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kc">True</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[][[]]] void'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[][[]]] void'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kc">True</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[[]][[][]]] void'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[[]][[][]]] void'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kc">False</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Functions Grouped by, er, Function with Examples</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#stack-chatter">Stack Chatter</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#list-words">List words</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#math-words">Math words</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#logic-and-comparison">Logic and Comparison</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#miscellaneous">Miscellaneous</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#combinators">Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#void"><code class="docutils literal notranslate"><span class="pre">void</span></code></a></li>
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Functions Grouped by, er, Function with Examples</a><ul>
+<li><a class="reference internal" href="#stack-chatter">Stack Chatter</a><ul>
+<li><a class="reference internal" href="#clear"><code class="docutils literal notranslate"><span class="pre">clear</span></code></a></li>
+<li><a class="reference internal" href="#dup-dupd"><code class="docutils literal notranslate"><span class="pre">dup</span></code> <code class="docutils literal notranslate"><span class="pre">dupd</span></code></a></li>
+<li><a class="reference internal" href="#enstacken-disenstacken-stack-unstack"><code class="docutils literal notranslate"><span class="pre">enstacken</span></code> <code class="docutils literal notranslate"><span class="pre">disenstacken</span></code> <code class="docutils literal notranslate"><span class="pre">stack</span></code> <code class="docutils literal notranslate"><span class="pre">unstack</span></code></a></li>
+<li><a class="reference internal" href="#pop-popd-popop"><code class="docutils literal notranslate"><span class="pre">pop</span></code> <code class="docutils literal notranslate"><span class="pre">popd</span></code> <code class="docutils literal notranslate"><span class="pre">popop</span></code></a></li>
+<li><a class="reference internal" href="#roll-rolldown-roll-rollup"><code class="docutils literal notranslate"><span class="pre">roll<</span></code> <code class="docutils literal notranslate"><span class="pre">rolldown</span></code> <code class="docutils literal notranslate"><span class="pre">roll></span></code> <code class="docutils literal notranslate"><span class="pre">rollup</span></code></a></li>
+<li><a class="reference internal" href="#swap"><code class="docutils literal notranslate"><span class="pre">swap</span></code></a></li>
+<li><a class="reference internal" href="#tuck-over"><code class="docutils literal notranslate"><span class="pre">tuck</span></code> <code class="docutils literal notranslate"><span class="pre">over</span></code></a></li>
+<li><a class="reference internal" href="#unit-quoted-unquoted"><code class="docutils literal notranslate"><span class="pre">unit</span></code> <code class="docutils literal notranslate"><span class="pre">quoted</span></code> <code class="docutils literal notranslate"><span class="pre">unquoted</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#list-words">List words</a><ul>
+<li><a class="reference internal" href="#concat-swoncat-shunt"><code class="docutils literal notranslate"><span class="pre">concat</span></code> <code class="docutils literal notranslate"><span class="pre">swoncat</span></code> <code class="docutils literal notranslate"><span class="pre">shunt</span></code></a></li>
+<li><a class="reference internal" href="#cons-swons-uncons"><code class="docutils literal notranslate"><span class="pre">cons</span></code> <code class="docutils literal notranslate"><span class="pre">swons</span></code> <code class="docutils literal notranslate"><span class="pre">uncons</span></code></a></li>
+<li><a class="reference internal" href="#first-second-third-rest"><code class="docutils literal notranslate"><span class="pre">first</span></code> <code class="docutils literal notranslate"><span class="pre">second</span></code> <code class="docutils literal notranslate"><span class="pre">third</span></code> <code class="docutils literal notranslate"><span class="pre">rest</span></code></a></li>
+<li><a class="reference internal" href="#flatten"><code class="docutils literal notranslate"><span class="pre">flatten</span></code></a></li>
+<li><a class="reference internal" href="#getitem-at-of-drop-take"><code class="docutils literal notranslate"><span class="pre">getitem</span></code> <code class="docutils literal notranslate"><span class="pre">at</span></code> <code class="docutils literal notranslate"><span class="pre">of</span></code> <code class="docutils literal notranslate"><span class="pre">drop</span></code> <code class="docutils literal notranslate"><span class="pre">take</span></code></a></li>
+<li><a class="reference internal" href="#remove"><code class="docutils literal notranslate"><span class="pre">remove</span></code></a></li>
+<li><a class="reference internal" href="#reverse"><code class="docutils literal notranslate"><span class="pre">reverse</span></code></a></li>
+<li><a class="reference internal" href="#size"><code class="docutils literal notranslate"><span class="pre">size</span></code></a></li>
+<li><a class="reference internal" href="#swaack"><code class="docutils literal notranslate"><span class="pre">swaack</span></code></a></li>
+<li><a class="reference internal" href="#choice-select"><code class="docutils literal notranslate"><span class="pre">choice</span></code> <code class="docutils literal notranslate"><span class="pre">select</span></code></a></li>
+<li><a class="reference internal" href="#zip"><code class="docutils literal notranslate"><span class="pre">zip</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#math-words">Math words</a><ul>
+<li><a class="reference internal" href="#add"><code class="docutils literal notranslate"><span class="pre">+</span></code> <code class="docutils literal notranslate"><span class="pre">add</span></code></a></li>
+<li><a class="reference internal" href="#sub"><code class="docutils literal notranslate"><span class="pre">-</span></code> <code class="docutils literal notranslate"><span class="pre">sub</span></code></a></li>
+<li><a class="reference internal" href="#mul"><code class="docutils literal notranslate"><span class="pre">*</span></code> <code class="docutils literal notranslate"><span class="pre">mul</span></code></a></li>
+<li><a class="reference internal" href="#div-floordiv-truediv"><code class="docutils literal notranslate"><span class="pre">/</span></code> <code class="docutils literal notranslate"><span class="pre">div</span></code> <code class="docutils literal notranslate"><span class="pre">floordiv</span></code> <code class="docutils literal notranslate"><span class="pre">truediv</span></code></a></li>
+<li><a class="reference internal" href="#mod-modulus-rem-remainder"><code class="docutils literal notranslate"><span class="pre">%</span></code> <code class="docutils literal notranslate"><span class="pre">mod</span></code> <code class="docutils literal notranslate"><span class="pre">modulus</span></code> <code class="docutils literal notranslate"><span class="pre">rem</span></code> <code class="docutils literal notranslate"><span class="pre">remainder</span></code></a></li>
+<li><a class="reference internal" href="#neg"><code class="docutils literal notranslate"><span class="pre">neg</span></code></a></li>
+<li><a class="reference internal" href="#pow"><code class="docutils literal notranslate"><span class="pre">pow</span></code></a></li>
+<li><a class="reference internal" href="#sqr-sqrt"><code class="docutils literal notranslate"><span class="pre">sqr</span></code> <code class="docutils literal notranslate"><span class="pre">sqrt</span></code></a></li>
+<li><a class="reference internal" href="#succ-pred"><code class="docutils literal notranslate"><span class="pre">++</span></code> <code class="docutils literal notranslate"><span class="pre">succ</span></code> <code class="docutils literal notranslate"><span class="pre">--</span></code> <code class="docutils literal notranslate"><span class="pre">pred</span></code></a></li>
+<li><a class="reference internal" href="#lshift-rshift"><code class="docutils literal notranslate"><span class="pre"><<</span></code> <code class="docutils literal notranslate"><span class="pre">lshift</span></code> <code class="docutils literal notranslate"><span class="pre">>></span></code> <code class="docutils literal notranslate"><span class="pre">rshift</span></code></a></li>
+<li><a class="reference internal" href="#average"><code class="docutils literal notranslate"><span class="pre">average</span></code></a></li>
+<li><a class="reference internal" href="#range-range-to-zero-down-to-zero"><code class="docutils literal notranslate"><span class="pre">range</span></code> <code class="docutils literal notranslate"><span class="pre">range_to_zero</span></code> <code class="docutils literal notranslate"><span class="pre">down_to_zero</span></code></a></li>
+<li><a class="reference internal" href="#product"><code class="docutils literal notranslate"><span class="pre">product</span></code></a></li>
+<li><a class="reference internal" href="#sum"><code class="docutils literal notranslate"><span class="pre">sum</span></code></a></li>
+<li><a class="reference internal" href="#min"><code class="docutils literal notranslate"><span class="pre">min</span></code></a></li>
+<li><a class="reference internal" href="#gcd"><code class="docutils literal notranslate"><span class="pre">gcd</span></code></a></li>
+<li><a class="reference internal" href="#least-fraction"><code class="docutils literal notranslate"><span class="pre">least_fraction</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#logic-and-comparison">Logic and Comparison</a><ul>
+<li><a class="reference internal" href="#truthy"><code class="docutils literal notranslate"><span class="pre">?</span></code> <code class="docutils literal notranslate"><span class="pre">truthy</span></code></a></li>
+<li><a class="reference internal" href="#and"><code class="docutils literal notranslate"><span class="pre">&</span></code> <code class="docutils literal notranslate"><span class="pre">and</span></code></a></li>
+<li><a class="reference internal" href="#ne"><code class="docutils literal notranslate"><span class="pre">!=</span></code> <code class="docutils literal notranslate"><span class="pre"><></span></code> <code class="docutils literal notranslate"><span class="pre">ne</span></code></a></li>
+<li><a class="reference internal" href="#xor"><code class="docutils literal notranslate"><span class="pre">^</span></code> <code class="docutils literal notranslate"><span class="pre">xor</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#miscellaneous">Miscellaneous</a><ul>
+<li><a class="reference internal" href="#help"><code class="docutils literal notranslate"><span class="pre">help</span></code></a></li>
+<li><a class="reference internal" href="#parse"><code class="docutils literal notranslate"><span class="pre">parse</span></code></a></li>
+<li><a class="reference internal" href="#run"><code class="docutils literal notranslate"><span class="pre">run</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#combinators">Combinators</a><ul>
+<li><a class="reference internal" href="#app1-app2-app3"><code class="docutils literal notranslate"><span class="pre">app1</span></code> <code class="docutils literal notranslate"><span class="pre">app2</span></code> <code class="docutils literal notranslate"><span class="pre">app3</span></code></a></li>
+<li><a class="reference internal" href="#anamorphism"><code class="docutils literal notranslate"><span class="pre">anamorphism</span></code></a></li>
+<li><a class="reference internal" href="#branch"><code class="docutils literal notranslate"><span class="pre">branch</span></code></a></li>
+<li><a class="reference internal" href="#cleave"><code class="docutils literal notranslate"><span class="pre">cleave</span></code></a></li>
+<li><a class="reference internal" href="#dip-dipd-dipdd"><code class="docutils literal notranslate"><span class="pre">dip</span></code> <code class="docutils literal notranslate"><span class="pre">dipd</span></code> <code class="docutils literal notranslate"><span class="pre">dipdd</span></code></a></li>
+<li><a class="reference internal" href="#dupdip"><code class="docutils literal notranslate"><span class="pre">dupdip</span></code></a></li>
+<li><a class="reference internal" href="#genrec-primrec"><code class="docutils literal notranslate"><span class="pre">genrec</span></code> <code class="docutils literal notranslate"><span class="pre">primrec</span></code></a></li>
+<li><a class="reference internal" href="#i"><code class="docutils literal notranslate"><span class="pre">i</span></code></a></li>
+<li><a class="reference internal" href="#ifte"><code class="docutils literal notranslate"><span class="pre">ifte</span></code></a></li>
+<li><a class="reference internal" href="#infra"><code class="docutils literal notranslate"><span class="pre">infra</span></code></a></li>
+<li><a class="reference internal" href="#loop"><code class="docutils literal notranslate"><span class="pre">loop</span></code></a></li>
+<li><a class="reference internal" href="#map-pam"><code class="docutils literal notranslate"><span class="pre">map</span></code> <code class="docutils literal notranslate"><span class="pre">pam</span></code></a></li>
+<li><a class="reference internal" href="#nullary-unary-binary-ternary"><code class="docutils literal notranslate"><span class="pre">nullary</span></code> <code class="docutils literal notranslate"><span class="pre">unary</span></code> <code class="docutils literal notranslate"><span class="pre">binary</span></code> <code class="docutils literal notranslate"><span class="pre">ternary</span></code></a></li>
+<li><a class="reference internal" href="#step"><code class="docutils literal notranslate"><span class="pre">step</span></code></a></li>
+<li><a class="reference internal" href="#times"><code class="docutils literal notranslate"><span class="pre">times</span></code></a></li>
+<li><a class="reference internal" href="#b"><code class="docutils literal notranslate"><span class="pre">b</span></code></a></li>
+<li><a class="reference internal" href="#while"><code class="docutils literal notranslate"><span class="pre">while</span></code></a></li>
+<li><a class="reference internal" href="#x"><code class="docutils literal notranslate"><span class="pre">x</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#void"><code class="docutils literal notranslate"><span class="pre">void</span></code></a></li>
</ul>
</li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="_sources/lib.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Function Reference — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Functions Grouped by, er, Function with Examples" href="lib.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="function-reference">
functions. Its main export is a Python function initialize() that
returns a dictionary of Joy functions suitable for use with the joy()
function.</p>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.BinaryBuiltinWrapper">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">BinaryBuiltinWrapper</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">f</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#BinaryBuiltinWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.BinaryBuiltinWrapper" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">BinaryBuiltinWrapper</code><span class="sig-paren">(</span><em>f</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#BinaryBuiltinWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.BinaryBuiltinWrapper" title="Permalink to this definition">¶</a></dt>
<dd><p>Wrap functions that take two arguments and return a single result.</p>
</dd></dl>
-<dl class="py class">
+<dl class="class">
<dt id="joy.library.DefinitionWrapper">
-<em class="property">class </em><code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">DefinitionWrapper</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">body_text</span></em>, <em class="sig-param"><span class="n">doc</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#DefinitionWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.DefinitionWrapper" title="Permalink to this definition">¶</a></dt>
+<em class="property">class </em><code class="descclassname">joy.library.</code><code class="descname">DefinitionWrapper</code><span class="sig-paren">(</span><em>name</em>, <em>body_text</em>, <em>doc=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#DefinitionWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.DefinitionWrapper" title="Permalink to this definition">¶</a></dt>
<dd><p>Provide implementation of defined functions, and some helper methods.</p>
-<dl class="py method">
+<dl class="classmethod">
<dt id="joy.library.DefinitionWrapper.add_def">
-<em class="property">classmethod </em><code class="sig-name descname">add_def</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">definition</span></em>, <em class="sig-param"><span class="n">dictionary</span></em>, <em class="sig-param"><span class="n">fail_fails</span><span class="o">=</span><span class="default_value">False</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#DefinitionWrapper.add_def"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.DefinitionWrapper.add_def" title="Permalink to this definition">¶</a></dt>
+<em class="property">classmethod </em><code class="descname">add_def</code><span class="sig-paren">(</span><em>definition</em>, <em>dictionary</em>, <em>fail_fails=False</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#DefinitionWrapper.add_def"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.DefinitionWrapper.add_def" title="Permalink to this definition">¶</a></dt>
<dd><p>Add the definition to the dictionary.</p>
</dd></dl>
-<dl class="py method">
+<dl class="classmethod">
<dt id="joy.library.DefinitionWrapper.add_definitions">
-<em class="property">classmethod </em><code class="sig-name descname">add_definitions</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">defs</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#DefinitionWrapper.add_definitions"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.DefinitionWrapper.add_definitions" title="Permalink to this definition">¶</a></dt>
+<em class="property">classmethod </em><code class="descname">add_definitions</code><span class="sig-paren">(</span><em>defs</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#DefinitionWrapper.add_definitions"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.DefinitionWrapper.add_definitions" title="Permalink to this definition">¶</a></dt>
<dd><p>Scan multi-line string defs for definitions and add them to the
dictionary.</p>
</dd></dl>
-<dl class="py method">
+<dl class="classmethod">
<dt id="joy.library.DefinitionWrapper.parse_definition">
-<em class="property">classmethod </em><code class="sig-name descname">parse_definition</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">defi</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#DefinitionWrapper.parse_definition"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.DefinitionWrapper.parse_definition" title="Permalink to this definition">¶</a></dt>
+<em class="property">classmethod </em><code class="descname">parse_definition</code><span class="sig-paren">(</span><em>defi</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#DefinitionWrapper.parse_definition"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.DefinitionWrapper.parse_definition" title="Permalink to this definition">¶</a></dt>
<dd><p>Given some text describing a Joy function definition parse it and
return a DefinitionWrapper.</p>
</dd></dl>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.FunctionWrapper">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">FunctionWrapper</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">f</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#FunctionWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.FunctionWrapper" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">FunctionWrapper</code><span class="sig-paren">(</span><em>f</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#FunctionWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.FunctionWrapper" title="Permalink to this definition">¶</a></dt>
<dd><p>Set name attribute.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.SimpleFunctionWrapper">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">SimpleFunctionWrapper</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">f</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#SimpleFunctionWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.SimpleFunctionWrapper" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">SimpleFunctionWrapper</code><span class="sig-paren">(</span><em>f</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#SimpleFunctionWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.SimpleFunctionWrapper" title="Permalink to this definition">¶</a></dt>
<dd><p>Wrap functions that take and return just a stack.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.UnaryBuiltinWrapper">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">UnaryBuiltinWrapper</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">f</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#UnaryBuiltinWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.UnaryBuiltinWrapper" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">UnaryBuiltinWrapper</code><span class="sig-paren">(</span><em>f</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#UnaryBuiltinWrapper"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.UnaryBuiltinWrapper" title="Permalink to this definition">¶</a></dt>
<dd><p>Wrap functions that take one argument and return a single result.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.add_aliases">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">add_aliases</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">D</span></em>, <em class="sig-param"><span class="n">A</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#add_aliases"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.add_aliases" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">add_aliases</code><span class="sig-paren">(</span><em>D</em>, <em>A</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#add_aliases"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.add_aliases" title="Permalink to this definition">¶</a></dt>
<dd><p>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.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.app1">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">app1</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#app1"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.app1" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">app1</code><span class="sig-paren">(</span><em>S</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#app1"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.app1" title="Permalink to this definition">¶</a></dt>
<dd><p>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.</p>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.app2">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">app2</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#app2"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.app2" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">app2</code><span class="sig-paren">(</span><em>S</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#app2"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.app2" title="Permalink to this definition">¶</a></dt>
<dd><p>Like app1 with two items.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="n">y</span> <span class="n">x</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="o">.</span> <span class="n">app2</span>
<span class="o">-----------------------------------</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.app3">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">app3</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#app3"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.app3" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">app3</code><span class="sig-paren">(</span><em>S</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#app3"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.app3" title="Permalink to this definition">¶</a></dt>
<dd><p>Like app1 with three items.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="n">z</span> <span class="n">y</span> <span class="n">x</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="o">.</span> <span class="n">app3</span>
<span class="o">-----------------------------------</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.b">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">b</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#b"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.b" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">b</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#b"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.b" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">==</span> <span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="n">dip</span> <span class="n">i</span>
<span class="o">...</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">b</span> <span class="o">==</span> <span class="o">...</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">i</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">i</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.branch">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">branch</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#branch"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.branch" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">branch</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#branch"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.branch" title="Permalink to this definition">¶</a></dt>
<dd><p>Use a Boolean value to select one of two quoted programs to run.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">branch</span> <span class="o">==</span> <span class="n">roll</span><span class="o"><</span> <span class="n">choice</span> <span class="n">i</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.choice">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">choice</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#choice"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.choice" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">choice</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#choice"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.choice" title="Permalink to this definition">¶</a></dt>
<dd><p>Use a Boolean value to select one of two items.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">A</span> <span class="n">B</span> <span class="kc">False</span> <span class="n">choice</span>
<span class="o">----------------------</span>
Boolean value (so empty string, zero, etc. are counted as false, etc.)</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.clear">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">clear</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#clear"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.clear" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">clear</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#clear"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.clear" title="Permalink to this definition">¶</a></dt>
<dd><p>Clear everything from the stack.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">clear</span> <span class="o">==</span> <span class="n">stack</span> <span class="p">[</span><span class="n">pop</span> <span class="n">stack</span><span class="p">]</span> <span class="n">loop</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.cmp_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">cmp_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#cmp_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.cmp_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">cmp_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#cmp_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.cmp_" title="Permalink to this definition">¶</a></dt>
<dd><p>cmp takes two values and three quoted programs on the stack and runs
one of the three depending on the results of comparing the two values:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">a</span> <span class="n">b</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">L</span><span class="p">]</span> <span class="nb">cmp</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.concat_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">concat_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#concat_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.concat_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">concat_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#concat_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.concat_" title="Permalink to this definition">¶</a></dt>
<dd><p>Concatinate the two lists on the top of the stack.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span><span class="p">]</span> <span class="p">[</span><span class="n">d</span> <span class="n">e</span> <span class="n">f</span><span class="p">]</span> <span class="n">concat</span>
<span class="o">----------------------------</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.cond">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">cond</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#cond"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.cond" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">cond</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#cond"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.cond" title="Permalink to this definition">¶</a></dt>
<dd><p>This combinator works like a case statement. It expects a single quote
on the stack that must contain zero or more condition quotes and a
default quote. Each condition clause should contain a quoted predicate
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.dip">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">dip</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#dip"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.dip" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">dip</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#dip"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.dip" title="Permalink to this definition">¶</a></dt>
<dd><p>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.</p>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.dipd">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">dipd</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#dipd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.dipd" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">dipd</code><span class="sig-paren">(</span><em>S</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#dipd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.dipd" title="Permalink to this definition">¶</a></dt>
<dd><p>Like dip but expects two items.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="n">y</span> <span class="n">x</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">dip</span>
<span class="o">---------------------</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.dipdd">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">dipdd</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#dipdd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.dipdd" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">dipdd</code><span class="sig-paren">(</span><em>S</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#dipdd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.dipdd" title="Permalink to this definition">¶</a></dt>
<dd><p>Like dip but expects three items.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="n">z</span> <span class="n">y</span> <span class="n">x</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">dip</span>
<span class="o">-----------------------</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.disenstacken">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">disenstacken</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#disenstacken"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.disenstacken" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">disenstacken</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#disenstacken"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.disenstacken" title="Permalink to this definition">¶</a></dt>
<dd><p>The disenstacken operator expects a list on top of the stack and makes that
the stack discarding the rest of the stack.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.divmod_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">divmod_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#divmod_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.divmod_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">divmod_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#divmod_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.divmod_" title="Permalink to this definition">¶</a></dt>
<dd><p>divmod(x, y) -> (quotient, remainder)</p>
<p>Return the tuple (x//y, x%y). Invariant: div*y + mod == x.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.drop">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">drop</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#drop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.drop" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">drop</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#drop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.drop" title="Permalink to this definition">¶</a></dt>
<dd><blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">drop</span> <span class="o">==</span> <span class="p">[</span><span class="n">rest</span><span class="p">]</span> <span class="n">times</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.dupdip">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">dupdip</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#dupdip"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.dupdip" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">dupdip</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#dupdip"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.dupdip" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">dupdip</span> <span class="o">==</span> <span class="n">dup</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">dip</span>
<span class="o">...</span> <span class="n">a</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">dupdip</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.floor">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">floor</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">x</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#floor"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.floor" title="Permalink to this definition">¶</a></dt>
-<dd><p>Return the floor of x as an Integral.
-This is the largest integer <= x.</p>
+<code class="descclassname">joy.library.</code><code class="descname">floor</code><span class="sig-paren">(</span><em>x</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#floor"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.floor" title="Permalink to this definition">¶</a></dt>
+<dd><p>Return the floor of x as a float.
+This is the largest integral value <= x.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.genrec">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">genrec</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#genrec"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.genrec" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">genrec</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#genrec"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.genrec" title="Permalink to this definition">¶</a></dt>
<dd><p>General Recursion Combinator.</p>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="k">if</span><span class="p">]</span> <span class="p">[</span><span class="n">then</span><span class="p">]</span> <span class="p">[</span><span class="n">rec1</span><span class="p">]</span> <span class="p">[</span><span class="n">rec2</span><span class="p">]</span> <span class="n">genrec</span>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="k">if</span><span class="p">]</span> <span class="p">[</span><span class="n">then</span><span class="p">]</span> <span class="p">[</span><span class="n">rec1</span><span class="p">]</span> <span class="p">[</span><span class="n">rec2</span><span class="p">]</span> <span class="n">genrec</span>
<span class="o">---------------------------------------------------------------------</span>
- <span class="p">[</span><span class="k">if</span><span class="p">]</span> <span class="p">[</span><span class="n">then</span><span class="p">]</span> <span class="p">[</span><span class="n">rec1</span> <span class="p">[[</span><span class="k">if</span><span class="p">]</span> <span class="p">[</span><span class="n">then</span><span class="p">]</span> <span class="p">[</span><span class="n">rec1</span><span class="p">]</span> <span class="p">[</span><span class="n">rec2</span><span class="p">]</span> <span class="n">genrec</span><span class="p">]</span> <span class="n">rec2</span><span class="p">]</span> <span class="n">ifte</span>
+ <span class="p">[</span><span class="k">if</span><span class="p">]</span> <span class="p">[</span><span class="n">then</span><span class="p">]</span> <span class="p">[</span><span class="n">rec1</span> <span class="p">[[</span><span class="k">if</span><span class="p">]</span> <span class="p">[</span><span class="n">then</span><span class="p">]</span> <span class="p">[</span><span class="n">rec1</span><span class="p">]</span> <span class="p">[</span><span class="n">rec2</span><span class="p">]</span> <span class="n">genrec</span><span class="p">]</span> <span class="n">rec2</span><span class="p">]</span> <span class="n">ifte</span>
</pre></div>
</div>
<p>From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun:
genrec combinator turns into an ifte combinator with a quoted copy of
the original definition in the else-part:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R1</span><span class="p">]</span> <span class="p">[</span><span class="n">R2</span><span class="p">]</span> <span class="n">genrec</span>
- <span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R1</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">R2</span><span class="p">]</span> <span class="n">ifte</span>
+ <span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R1</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">R2</span><span class="p">]</span> <span class="n">ifte</span>
</pre></div>
</div>
<p>Primitive recursive functions are those where R2 == i.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">P</span> <span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R</span><span class="p">]</span> <span class="n">tailrec</span>
- <span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">i</span><span class="p">]</span> <span class="n">ifte</span>
- <span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R</span> <span class="n">P</span><span class="p">]</span> <span class="n">ifte</span>
+ <span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="n">i</span><span class="p">]</span> <span class="n">ifte</span>
+ <span class="o">==</span> <span class="p">[</span><span class="n">I</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">R</span> <span class="n">P</span><span class="p">]</span> <span class="n">ifte</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.getitem">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">getitem</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#getitem"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.getitem" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">getitem</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#getitem"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.getitem" title="Permalink to this definition">¶</a></dt>
<dd><blockquote>
<div><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">getitem</span> <span class="o">==</span> <span class="n">drop</span> <span class="n">first</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.help_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">help_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#help_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.help_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">help_</code><span class="sig-paren">(</span><em>S</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#help_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.help_" title="Permalink to this definition">¶</a></dt>
<dd><p>Accepts a quoted symbol on the top of the stack and prints its docs.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.i">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">i</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#i"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.i" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">i</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#i"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.i" title="Permalink to this definition">¶</a></dt>
<dd><p>The i combinator expects a quoted program on the stack and unpacks it
onto the pending expression for evaluation.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">i</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.id_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">id_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#id_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.id_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">id_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#id_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.id_" title="Permalink to this definition">¶</a></dt>
<dd><p>The identity function.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.infer_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">infer_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#infer_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.infer_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">infer_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#infer_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.infer_" title="Permalink to this definition">¶</a></dt>
<dd><p>Attempt to infer the stack effect of a Joy expression.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.infra">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">infra</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#infra"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.infra" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">infra</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#infra"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.infra" title="Permalink to this definition">¶</a></dt>
<dd><p>Accept a quoted program and a list on the stack and run the program
with the list as its stack. Does not affect the rest of the stack.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="p">[</span><span class="n">a</span> <span class="n">b</span> <span class="n">c</span><span class="p">]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="o">.</span> <span class="n">infra</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.initialize">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">initialize</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#initialize"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.initialize" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">initialize</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#initialize"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.initialize" title="Permalink to this definition">¶</a></dt>
<dd><p>Return a dictionary of Joy functions for use with joy().</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.inscribe">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">inscribe</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">function</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#inscribe"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.inscribe" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">inscribe</code><span class="sig-paren">(</span><em>function</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#inscribe"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.inscribe" title="Permalink to this definition">¶</a></dt>
<dd><p>A decorator to inscribe functions into the default dictionary.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.inscribe_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">inscribe_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#inscribe_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.inscribe_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">inscribe_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#inscribe_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.inscribe_" title="Permalink to this definition">¶</a></dt>
<dd><blockquote>
<div><p>Create a new Joy function definition in the Joy dictionary. A
definition is given as a string with a name followed by a double
equal sign then one or more Joy functions, the body. for example:</p>
<blockquote>
-<div><p>sqr == dup mul</p>
-</div></blockquote>
+<div>sqr == dup mul</div></blockquote>
<p>If you want the definition to persist over restarts, enter it into
the definitions.txt resource.</p>
</div></blockquote>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.loop">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">loop</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#loop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.loop" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">loop</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#loop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.loop" title="Permalink to this definition">¶</a></dt>
<dd><p>Basic loop combinator.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="kc">True</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">loop</span>
<span class="o">-----------------------</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.map_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">map_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#map_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.map_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">map_</code><span class="sig-paren">(</span><em>S</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#map_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.map_" title="Permalink to this definition">¶</a></dt>
<dd><p>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.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.max_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">max_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#max_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.max_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">max_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#max_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.max_" title="Permalink to this definition">¶</a></dt>
<dd><p>Given a list find the maximum.
Stack effect:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n2</span><span class="o">*</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.min_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">min_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#min_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.min_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">min_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#min_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.min_" title="Permalink to this definition">¶</a></dt>
<dd><p>Given a list find the minimum.
Stack effect:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n2</span><span class="o">*</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.parse">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">parse</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#parse"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.parse" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">parse</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#parse"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.parse" title="Permalink to this definition">¶</a></dt>
<dd><p>Parse the string on the stack to a Joy expression.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.pm">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">pm</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#pm"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.pm" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">pm</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#pm"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.pm" title="Permalink to this definition">¶</a></dt>
<dd><p>Plus or minus</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="n">a</span> <span class="n">b</span> <span class="n">pm</span>
<span class="o">-------------</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.pred">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">pred</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#pred"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.pred" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">pred</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#pred"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.pred" title="Permalink to this definition">¶</a></dt>
<dd><p>Decrement TOS.
Stack effect:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
+<dt id="joy.library.primrec">
+<code class="descclassname">joy.library.</code><code class="descname">primrec</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#primrec"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.primrec" title="Permalink to this definition">¶</a></dt>
+<dd><p>From the “Overview of the language JOY”:</p>
+<p>> The primrec combinator expects two quoted programs in addition to a
+data parameter. For an integer data parameter it works like this: If
+the data parameter is zero, then the first quotation has to produce
+the value to be returned. If the data parameter is positive then the
+second has to combine the data parameter with the result of applying
+the function to its predecessor.</p>
+<p>5 [1] [*] primrec</p>
+<p>> Then primrec tests whether the top element on the stack (initially
+the 5) is equal to zero. If it is, it pops it off and executes one of
+the quotations, the [1] which leaves 1 on the stack as the result.
+Otherwise it pushes a decremented copy of the top element and
+recurses. On the way back from the recursion it uses the other
+quotation, [*], to multiply what is now a factorial on top of the
+stack by the second element on the stack.</p>
+<blockquote>
+<div><blockquote>
+<div>n [Base] [Recur] primrec</div></blockquote>
+<p>0 [Base] [Recur] primrec</p>
+</div></blockquote>
+<blockquote>
+<div><blockquote>
+<div>Base</div></blockquote>
+<p>n [Base] [Recur] primrec</p>
+</div></blockquote>
+<dl class="docutils">
+<dt>—————————————— n > 0</dt>
+<dd>n (n-1) [Base] [Recur] primrec Recur</dd>
+</dl>
+</dd></dl>
+
+<dl class="function">
<dt id="joy.library.remove">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">remove</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#remove"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.remove" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">remove</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#remove"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.remove" title="Permalink to this definition">¶</a></dt>
<dd><p>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.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">1</span><span class="p">]</span> <span class="mi">1</span> <span class="n">remove</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.reverse">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">reverse</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#reverse"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.reverse" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">reverse</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#reverse"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.reverse" title="Permalink to this definition">¶</a></dt>
<dd><p>Reverse the list on the top of the stack.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">reverse</span> <span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="n">shunt</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.select">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">select</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#select"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.select" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">select</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#select"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.select" title="Permalink to this definition">¶</a></dt>
<dd><p>Use a Boolean value to select one of two items from a sequence.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="n">A</span> <span class="n">B</span><span class="p">]</span> <span class="kc">False</span> <span class="n">select</span>
<span class="o">------------------------</span>
Boolean value (so empty string, zero, etc. are counted as false, etc.)</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.sharing">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">sharing</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#sharing"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.sharing" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">sharing</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#sharing"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.sharing" title="Permalink to this definition">¶</a></dt>
<dd><p>Print redistribution information.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.shunt">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">shunt</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#shunt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.shunt" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">shunt</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#shunt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.shunt" title="Permalink to this definition">¶</a></dt>
<dd><p>Like concat but reverses the top list into the second.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">shunt</span> <span class="o">==</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">step</span> <span class="o">==</span> <span class="n">reverse</span> <span class="n">swap</span> <span class="n">concat</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.sort_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">sort_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#sort_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.sort_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">sort_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#sort_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.sort_" title="Permalink to this definition">¶</a></dt>
<dd><p>Given a list return it sorted.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.sqrt">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">sqrt</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">a</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#sqrt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.sqrt" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">sqrt</code><span class="sig-paren">(</span><em>a</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#sqrt"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.sqrt" title="Permalink to this definition">¶</a></dt>
<dd><p>Return the square root of the number a.
Negative numbers return complex roots.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.step">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">step</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#step"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.step" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">step</code><span class="sig-paren">(</span><em>S</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#step"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.step" title="Permalink to this definition">¶</a></dt>
<dd><p>Run a quoted program on each item in a sequence.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="p">[]</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="o">.</span> <span class="n">step</span>
<span class="o">-----------------------</span>
on top of the stack.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.succ">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">succ</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#succ"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.succ" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">succ</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#succ"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.succ" title="Permalink to this definition">¶</a></dt>
<dd><p>Increment TOS.
Stack effect:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.sum_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">sum_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#sum_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.sum_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">sum_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#sum_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.sum_" title="Permalink to this definition">¶</a></dt>
<dd><p>Given a quoted sequence of numbers return the sum.</p>
<blockquote>
-<div><p>sum == 0 swap [+] step</p>
-</div></blockquote>
+<div>sum == 0 swap [+] step</div></blockquote>
<p>Stack effect:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n2</span><span class="o">*</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.take">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">take</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#take"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.take" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">take</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#take"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.take" title="Permalink to this definition">¶</a></dt>
<dd><blockquote>
<div><p>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
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.times">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">times</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#times"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.times" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">times</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#times"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.times" title="Permalink to this definition">¶</a></dt>
<dd><p>times == [– dip] cons [swap] infra [0 >] swap while pop</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">...</span> <span class="n">n</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="o">.</span> <span class="n">times</span>
<span class="o">---------------------</span> <span class="n">w</span><span class="o">/</span> <span class="n">n</span> <span class="o"><=</span> <span class="mi">0</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.unique">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">unique</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#unique"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.unique" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">unique</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#unique"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.unique" title="Permalink to this definition">¶</a></dt>
<dd><p>Given a list remove duplicate items.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.void">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">void</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#void"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.void" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">void</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#void"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.void" title="Permalink to this definition">¶</a></dt>
<dd><p>True if the form on TOS is void otherwise False.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.warranty">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">warranty</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#warranty"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.warranty" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">warranty</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#warranty"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.warranty" title="Permalink to this definition">¶</a></dt>
<dd><p>Print warranty information.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.words">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">words</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#words"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.words" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">words</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#words"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.words" title="Permalink to this definition">¶</a></dt>
<dd><p>Print all the words in alphabetical order.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.x">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">x</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#x"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.x" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">x</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#x"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.x" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">==</span> <span class="n">dup</span> <span class="n">i</span>
<span class="o">...</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">x</span> <span class="o">=</span> <span class="o">...</span> <span class="p">[</span><span class="n">Q</span><span class="p">]</span> <span class="n">dup</span> <span class="n">i</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.yin_functions">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">yin_functions</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#yin_functions"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.yin_functions" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">yin_functions</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#yin_functions"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.yin_functions" title="Permalink to this definition">¶</a></dt>
<dd><p>Return a dict of named stack effects.</p>
<p>“Yin” functions are those that only rearrange items in stacks and
can be defined completely by their stack effects. This means they
can be auto-compiled.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.library.zip_">
-<code class="sig-prename descclassname">joy.library.</code><code class="sig-name descname">zip_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">S</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#zip_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.zip_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.library.</code><code class="descname">zip_</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/library.html#zip_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.library.zip_" title="Permalink to this definition">¶</a></dt>
<dd><p>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.</p>
</dd></dl>
</div>
<div class="section" id="module-joy.utils.generated_library">
<span id="auto-generated-functions"></span><h2>Auto-generated Functions<a class="headerlink" href="#module-joy.utils.generated_library" title="Permalink to this headline">¶</a></h2>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.ccons">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">ccons</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#ccons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.ccons" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">ccons</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#ccons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.ccons" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="p">[</span><span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">...</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.cons">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">cons</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#cons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.cons" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">cons</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#cons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.cons" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">...</span><span class="mi">0</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">...</span><span class="mi">0</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.dup">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">dup</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#dup"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.dup" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">dup</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#dup"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.dup" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.dupd">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">dupd</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#dupd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.dupd" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">dupd</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#dupd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.dupd" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.dupdd">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">dupdd</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#dupdd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.dupdd" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">dupdd</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#dupdd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.dupdd" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.first">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">first</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#first"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.first" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">first</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#first"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.first" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.first_two">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">first_two</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#first_two"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.first_two" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">first_two</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#first_two"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.first_two" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.fourth">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">fourth</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#fourth"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.fourth" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">fourth</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#fourth"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.fourth" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a4</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="n">a4</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.over">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">over</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#over"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.over" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">over</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#over"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.over" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.pop">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">pop</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#pop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.pop" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">pop</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#pop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.pop" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.popd">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">popd</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popd" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">popd</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popd" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.popdd">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">popdd</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popdd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popdd" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">popdd</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popdd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popdd" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.popop">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">popop</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popop" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">popop</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popop" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.popopd">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">popopd</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popopd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popopd" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">popopd</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popopd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popopd" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.popopdd">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">popopdd</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popopdd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popopdd" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">popopdd</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#popopdd"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.popopdd" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a4</span> <span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.rest">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">rest</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#rest"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.rest" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">rest</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#rest"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.rest" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="o">...</span><span class="mi">0</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="mi">0</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.rolldown">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">rolldown</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#rolldown"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.rolldown" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">rolldown</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#rolldown"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.rolldown" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.rollup">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">rollup</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#rollup"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.rollup" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">rollup</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#rollup"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.rollup" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a1</span> <span class="n">a2</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.rrest">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">rrest</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#rrest"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.rrest" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">rrest</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#rrest"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.rrest" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.second">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">second</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#second"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.second" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">second</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#second"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.second" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="n">a2</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.stack">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">stack</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.stack" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">stack</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.stack" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.stuncons">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">stuncons</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#stuncons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.stuncons" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">stuncons</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#stuncons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.stuncons" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a1</span> <span class="n">a1</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.stununcons">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">stununcons</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#stununcons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.stununcons" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">stununcons</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#stununcons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.stununcons" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a1</span> <span class="n">a2</span> <span class="p">[</span><span class="o">...</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.swaack">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">swaack</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#swaack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.swaack" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">swaack</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#swaack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.swaack" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="mi">0</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.swap">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">swap</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#swap"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.swap" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">swap</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#swap"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.swap" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.swons">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">swons</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#swons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.swons" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">swons</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#swons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.swons" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">...</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.third">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">third</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#third"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.third" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">third</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#third"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.third" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="n">a3</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.tuck">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">tuck</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#tuck"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.tuck" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">tuck</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#tuck"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.tuck" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a2</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.uncons">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">uncons</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#uncons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.uncons" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">uncons</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#uncons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.uncons" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="o">...</span><span class="mi">0</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">...</span><span class="mi">0</span><span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.unit">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">unit</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#unit"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.unit" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">unit</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#unit"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.unit" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="p">])</span>
</pre></div>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.generated_library.unswons">
-<code class="sig-prename descclassname">joy.utils.generated_library.</code><code class="sig-name descname">unswons</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#unswons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.unswons" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.generated_library.</code><code class="descname">unswons</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/generated_library.html#unswons"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.generated_library.unswons" title="Permalink to this definition">¶</a></dt>
<dd><div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Function Reference</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#module-joy.library"><code class="docutils literal notranslate"><span class="pre">joy.library</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="#module-joy.utils.generated_library">Auto-generated Functions</a></li>
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Function Reference</a><ul>
+<li><a class="reference internal" href="#module-joy.library"><code class="docutils literal notranslate"><span class="pre">joy.library</span></code></a></li>
+<li><a class="reference internal" href="#module-joy.utils.generated_library">Auto-generated Functions</a></li>
</ul>
</li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="_sources/library.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Categorical Programming — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="The Four Fundamental Operations of Definite Action" href="The_Four_Operations.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="categorical-programming">
<p>In Manfred von Thun’s article <a class="reference external" href="http://www.kevinalbrecht.com/code/joy-mirror/j08cnt.html">Joy compared with other functional languages</a> he asks, “Could the language of categories be used for writing programs? Any lambda expression can be translated into a categorical expression, so the language of categories is expressively complete. But this does not make it a suitable language for writing programs. As it stands it is a very low-level language.”</p>
<p>In <a class="reference external" href="http://conal.net/papers/compiling-to-categories/">Compiling to categories</a> Conal Elliott give a taste of what this might mean.</p>
<blockquote>
-<div><p>It is well-known that the simply typed lambda-calculus is modeled by any cartesian closed category (CCC). This correspondence suggests giving typed functional programs a variety of interpretations, each corresponding to a different category. A convenient way to realize this idea is as a collection of meaning-preserving transformations added to an existing compiler, such as GHC for Haskell. This paper describes such an implementation and demonstrates its use for a variety of interpretations including hardware circuits, automatic differentiation, incremental computation, and interval analysis. Each such interpretation is a category easily defined in Haskell (outside of the compiler). The general technique appears to provide a compelling alternative to deeply embedded domain-specific languages.</p>
-</div></blockquote>
+<div>It is well-known that the simply typed lambda-calculus is modeled by any cartesian closed category (CCC). This correspondence suggests giving typed functional programs a variety of interpretations, each corresponding to a different category. A convenient way to realize this idea is as a collection of meaning-preserving transformations added to an existing compiler, such as GHC for Haskell. This paper describes such an implementation and demonstrates its use for a variety of interpretations including hardware circuits, automatic differentiation, incremental computation, and interval analysis. Each such interpretation is a category easily defined in Haskell (outside of the compiler). The general technique appears to provide a compelling alternative to deeply embedded domain-specific languages.</div></blockquote>
<p>What he’s doing is translating lambda forms into a kind of “point-free” style that is very close to Joy code (although more verbose) and then showing how to instantiate that code over different categories to get several different kinds of program out of the same code.</p>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
-</ul>
-</li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Categorical.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>∂RE — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="prev" title="The Four Fundamental Operations of Definite Action" href="The_Four_Operations.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="re">
<h1>∂RE<a class="headerlink" href="#re" title="Permalink to this headline">¶</a></h1>
-<div class="section" id="brzozowski-s-derivatives-of-regular-expressions">
-<h2>Brzozowski’s Derivatives of Regular Expressions<a class="headerlink" href="#brzozowski-s-derivatives-of-regular-expressions" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="brzozowskis-derivatives-of-regular-expressions">
+<h2>Brzozowski’s Derivatives of Regular Expressions<a class="headerlink" href="#brzozowskis-derivatives-of-regular-expressions" title="Permalink to this headline">¶</a></h2>
<p>Legend:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>∧ intersection
∨ union
</div>
<div class="section" id="implementation">
<h2>Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">partial</span> <span class="k">as</span> <span class="n">curry</span>
-<span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">product</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">functools</span> <span class="k">import</span> <span class="n">partial</span> <span class="k">as</span> <span class="n">curry</span>
+<span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">product</span>
</pre></div>
</div>
<div class="section" id="and">
<h3><code class="docutils literal notranslate"><span class="pre">ϕ</span></code> and <code class="docutils literal notranslate"><span class="pre">λ</span></code><a class="headerlink" href="#and" title="Permalink to this headline">¶</a></h3>
<p>The empty set and the set of just the empty string.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">phi</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">()</span> <span class="c1"># ϕ</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">phi</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">()</span> <span class="c1"># ϕ</span>
<span class="n">y</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">''</span><span class="p">})</span> <span class="c1"># λ</span>
</pre></div>
</div>
alphabet with two symbols (if you had to.)</p>
<p>I chose the names <code class="docutils literal notranslate"><span class="pre">O</span></code> and <code class="docutils literal notranslate"><span class="pre">l</span></code> (uppercase “o” and lowercase “L”) to
look like <code class="docutils literal notranslate"><span class="pre">0</span></code> and <code class="docutils literal notranslate"><span class="pre">1</span></code> (zero and one) respectively.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">syms</span> <span class="o">=</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'0'</span><span class="p">}),</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'1'</span><span class="p">})</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">syms</span> <span class="o">=</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'0'</span><span class="p">}),</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'1'</span><span class="p">})</span>
</pre></div>
</div>
</div>
</pre></div>
</div>
<p>Where <code class="docutils literal notranslate"><span class="pre">R</span></code> and <code class="docutils literal notranslate"><span class="pre">S</span></code> stand for <em>regular expressions</em>.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">AND</span><span class="p">,</span> <span class="n">CONS</span><span class="p">,</span> <span class="n">KSTAR</span><span class="p">,</span> <span class="n">NOT</span><span class="p">,</span> <span class="n">OR</span> <span class="o">=</span> <span class="s1">'and cons * not or'</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="c1"># Tags are just strings.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">AND</span><span class="p">,</span> <span class="n">CONS</span><span class="p">,</span> <span class="n">KSTAR</span><span class="p">,</span> <span class="n">NOT</span><span class="p">,</span> <span class="n">OR</span> <span class="o">=</span> <span class="s1">'and cons * not or'</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="c1"># Tags are just strings.</span>
</pre></div>
</div>
<p>Because they are formed of <code class="docutils literal notranslate"><span class="pre">frozenset</span></code>, <code class="docutils literal notranslate"><span class="pre">tuple</span></code> and <code class="docutils literal notranslate"><span class="pre">str</span></code> objects
</div>
<div class="section" id="string-representation-of-re-datastructures">
<h3>String Representation of RE Datastructures<a class="headerlink" href="#string-representation-of-re-datastructures" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">stringy</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">stringy</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
<span class="sd">'''</span>
<span class="sd"> Return a nice string repr for a regular expression datastructure.</span>
<span class="sd"> '''</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">I</span> <span class="o">=</span> <span class="p">(</span><span class="mi">0</span><span class="o">|</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">I</span> <span class="o">=</span> <span class="p">(</span><span class="n">KSTAR</span><span class="p">,</span> <span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">I</span> <span class="o">=</span> <span class="p">(</span><span class="n">KSTAR</span><span class="p">,</span> <span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">I</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">I</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">.</span>
</pre></div>
</div>
<p>Note that it contains one of everything.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="n">I</span><span class="p">))))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="n">I</span><span class="p">))))</span>
<span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
<span class="n">c</span> <span class="o">=</span> <span class="p">(</span><span class="n">CONS</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="p">(</span><span class="n">KSTAR</span><span class="p">,</span> <span class="n">l</span><span class="p">))</span>
<span class="n">it</span> <span class="o">=</span> <span class="p">(</span><span class="n">AND</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">NOT</span><span class="p">,</span> <span class="p">(</span><span class="n">OR</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">)))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">stringy</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">.</span><span class="mf">111.</span><span class="p">)</span> <span class="o">&</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">11</span><span class="o">*</span><span class="p">)</span><span class="s1">')</span>
<div class="section" id="nully">
<h3><code class="docutils literal notranslate"><span class="pre">nully()</span></code><a class="headerlink" href="#nully" title="Permalink to this headline">¶</a></h3>
<p>Let’s get that auxiliary predicate function <code class="docutils literal notranslate"><span class="pre">δ</span></code> out of the way.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">nully</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">nully</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
<span class="sd">'''</span>
<span class="sd"> δ - Return λ if λ ⊆ R otherwise ϕ.</span>
<span class="sd"> '''</span>
<p>This is the straightforward version with no “compaction”. It works fine,
but does waaaay too much work because the expressions grow each
derivation.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">derv</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
</div>
<div class="section" id="compaction-rules">
<h3>Compaction Rules<a class="headerlink" href="#compaction-rules" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_compaction_rule</span><span class="p">(</span><span class="n">relation</span><span class="p">,</span> <span class="n">one</span><span class="p">,</span> <span class="n">zero</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_compaction_rule</span><span class="p">(</span><span class="n">relation</span><span class="p">,</span> <span class="n">one</span><span class="p">,</span> <span class="n">zero</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="n">b</span> <span class="k">if</span> <span class="n">a</span> <span class="o">==</span> <span class="n">one</span> <span class="k">else</span> <span class="c1"># R*1 = 1*R = R</span>
<span class="n">a</span> <span class="k">if</span> <span class="n">b</span> <span class="o">==</span> <span class="n">one</span> <span class="k">else</span>
</pre></div>
</div>
<p>An elegant symmetry.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># R ∧ I = I ∧ R = R</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># R ∧ I = I ∧ R = R</span>
<span class="c1"># R ∧ ϕ = ϕ ∧ R = ϕ</span>
<span class="n">_and</span> <span class="o">=</span> <span class="n">curry</span><span class="p">(</span><span class="n">_compaction_rule</span><span class="p">,</span> <span class="n">AND</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">phi</span><span class="p">)</span>
<p>We can save re-processing by remembering results we have already
computed. RE datastructures are immutable and the <code class="docutils literal notranslate"><span class="pre">derv()</span></code> functions
are <em>pure</em> so this is fine.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Memo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Memo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">f</span> <span class="o">=</span> <span class="n">f</span>
<span class="bp">self</span><span class="o">.</span><span class="n">calls</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">hits</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mem</span> <span class="o">=</span> <span class="p">{}</span>
- <span class="k">def</span> <span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">calls</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mem</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
<h3>With “Compaction”<a class="headerlink" href="#with-compaction" title="Permalink to this headline">¶</a></h3>
<p>This version uses the rules above to perform compaction. It keeps the
expressions from growing too large.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D_compaction</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">D_compaction</span><span class="p">(</span><span class="n">symbol</span><span class="p">):</span>
<span class="nd">@Memo</span>
<span class="k">def</span> <span class="nf">derv</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
</div>
</div>
</div>
-<div class="section" id="let-s-try-it-out">
-<h2>Let’s try it out…<a class="headerlink" href="#let-s-try-it-out" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="lets-try-it-out">
+<h2>Let’s try it out…<a class="headerlink" href="#lets-try-it-out" title="Permalink to this headline">¶</a></h2>
<p>(FIXME: redo.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">o</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">o</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
<span class="n">REs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
<span class="n">N</span> <span class="o">=</span> <span class="mi">5</span>
<span class="n">names</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">product</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">N</span> <span class="o">*</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)])))</span>
</div>
<div class="section" id="larger-alphabets">
<h2>Larger Alphabets<a class="headerlink" href="#larger-alphabets" title="Permalink to this headline">¶</a></h2>
-<p>We could parse larger alphabets by defining patterns for e.g. each byte
+<p>We could parse larger alphabets by defining patterns for e.g. each byte
of the ASCII code. Or we can generalize this code. If you study the code
above you’ll see that we never use the “set-ness” of the symbols <code class="docutils literal notranslate"><span class="pre">O</span></code>
and <code class="docutils literal notranslate"><span class="pre">l</span></code>. The only time Python set operators (<code class="docutils literal notranslate"><span class="pre">&</span></code> and <code class="docutils literal notranslate"><span class="pre">|</span></code>) appear
</pre></div>
</div>
<p>Says, “Three or more 1’s and not ending in 01 nor composed of all 1’s.”</p>
-<div class="figure align-default" id="id2">
-<img alt="omg.svg" src="notebooks/attachment:omg.svg" /><p class="caption"><span class="caption-text">omg.svg</span><a class="headerlink" href="#id2" title="Permalink to this image">¶</a></p>
+<div class="figure" id="id2">
+<img alt="omg.svg" src="notebooks/attachment:omg.svg" /><p class="caption"><span class="caption-text">omg.svg</span></p>
</div>
<p>Start at <code class="docutils literal notranslate"><span class="pre">a</span></code> and follow the transition arrows according to their
labels. Accepting states have a double outline. (Graphic generated with
<p>You can see the one-way nature of the <code class="docutils literal notranslate"><span class="pre">g</span></code> state and the <code class="docutils literal notranslate"><span class="pre">hij</span></code> “trap”
in the way that the <code class="docutils literal notranslate"><span class="pre">.111.</span></code> on the left-hand side of the <code class="docutils literal notranslate"><span class="pre">&</span></code>
disappears once it has been matched.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
-<span class="kn">from</span> <span class="nn">pprint</span> <span class="kn">import</span> <span class="n">pprint</span>
-<span class="kn">from</span> <span class="nn">string</span> <span class="kn">import</span> <span class="n">ascii_lowercase</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">defaultdict</span>
+<span class="kn">from</span> <span class="nn">pprint</span> <span class="k">import</span> <span class="n">pprint</span>
+<span class="kn">from</span> <span class="nn">string</span> <span class="k">import</span> <span class="n">ascii_lowercase</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">d0</span><span class="p">,</span> <span class="n">d1</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">d0</span><span class="p">,</span> <span class="n">d1</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="explore">
<h3><code class="docutils literal notranslate"><span class="pre">explore()</span></code><a class="headerlink" href="#explore" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">explore</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">explore</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
<span class="c1"># Don't have more than 26 states...</span>
<span class="n">names</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">ascii_lowercase</span><span class="p">)</span><span class="o">.</span><span class="n">next</span><span class="p">)</span>
<span class="k">return</span> <span class="n">table</span><span class="p">,</span> <span class="n">accepting</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span> <span class="o">=</span> <span class="n">explore</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span> <span class="o">=</span> <span class="n">explore</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
<span class="n">table</span>
</pre></div>
</div>
<span class="p">(</span><span class="s1">'j'</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">'h'</span><span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">accepting</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">accepting</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="s1">'h'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">}</span>
<h3>Generate Diagram<a class="headerlink" href="#generate-diagram" title="Permalink to this headline">¶</a></h3>
<p>Once we have the FSM table and the set of accepting states we can
generate the diagram above.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">_template</span> <span class="o">=</span> <span class="s1">'''</span><span class="se">\</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">_template</span> <span class="o">=</span> <span class="s1">'''</span><span class="se">\</span>
<span class="s1">digraph finite_state_machine {</span>
<span class="s1"> rankdir=LR;</span>
<span class="s1"> size="8,5"</span>
<span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">make_graph</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">make_graph</span><span class="p">(</span><span class="n">table</span><span class="p">,</span> <span class="n">accepting</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">digraph</span> <span class="n">finite_state_machine</span> <span class="p">{</span>
<h4>Trampoline Function<a class="headerlink" href="#trampoline-function" title="Permalink to this headline">¶</a></h4>
<p>Python has no GOTO statement but we can fake it with a “trampoline”
function.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">trampoline</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="n">jump_from</span><span class="p">,</span> <span class="n">accepting</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">trampoline</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="n">jump_from</span><span class="p">,</span> <span class="n">accepting</span><span class="p">):</span>
<span class="n">I</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">input_</span><span class="p">)</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<h4>Stream Functions<a class="headerlink" href="#stream-functions" title="Permalink to this headline">¶</a></h4>
<p>Little helpers to process the iterator of our data (a “stream” of “1”
and “0” characters, not bits.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">getch</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="nb">int</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">I</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">getch</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="nb">int</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">I</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_1</span><span class="p">(</span><span class="n">I</span><span class="p">):</span>
code. (You have to imagine that these are GOTO statements in C or
branches in assembly and that the state names are branch destination
labels.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">c</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">c</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<span class="n">b</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">_0</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="ow">or</span> <span class="n">d</span>
<span class="n">c</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">e</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<span class="n">d</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">I</span><span class="p">:</span> <span class="n">f</span> <span class="k">if</span> <span class="n">getch</span><span class="p">(</span><span class="n">I</span><span class="p">)</span> <span class="k">else</span> <span class="n">b</span>
<p>Note that the implementations of <code class="docutils literal notranslate"><span class="pre">h</span></code> and <code class="docutils literal notranslate"><span class="pre">g</span></code> are identical ergo
<code class="docutils literal notranslate"><span class="pre">h</span> <span class="pre">=</span> <span class="pre">g</span></code> and we could eliminate one in the code but <code class="docutils literal notranslate"><span class="pre">h</span></code> is an
accepting state and <code class="docutils literal notranslate"><span class="pre">g</span></code> isn’t.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">acceptable</span><span class="p">(</span><span class="n">input_</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">acceptable</span><span class="p">(</span><span class="n">input_</span><span class="p">):</span>
<span class="k">return</span> <span class="n">trampoline</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="p">{</span><span class="n">h</span><span class="p">,</span> <span class="n">i</span><span class="p">})</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">5</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">5</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="nb">bin</span><span class="p">(</span><span class="n">n</span><span class="p">)[</span><span class="mi">2</span><span class="p">:]</span>
<span class="nb">print</span> <span class="s1">'</span><span class="si">%05s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">s</span><span class="p">,</span> <span class="n">acceptable</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
</pre></div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="n">d10</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</pre></div>
</div>
-<p>â\80\98’’</p>
+<p>â\80\99’’</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">j</span> <span class="o">=</span> <span class="n">d1</span><span class="p">(</span><span class="n">d0</span><span class="p">(</span><span class="n">j</span><span class="p">))</span>
</pre></div>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">∂RE</a><ul>
+<li><a class="reference internal" href="#brzozowskis-derivatives-of-regular-expressions">Brzozowski’s Derivatives of Regular Expressions</a></li>
+<li><a class="reference internal" href="#implementation">Implementation</a><ul>
+<li><a class="reference internal" href="#and"><code class="docutils literal notranslate"><span class="pre">ϕ</span></code> and <code class="docutils literal notranslate"><span class="pre">λ</span></code></a></li>
+<li><a class="reference internal" href="#two-letter-alphabet">Two-letter Alphabet</a></li>
+<li><a class="reference internal" href="#representing-regular-expressions">Representing Regular Expressions</a></li>
+<li><a class="reference internal" href="#string-representation-of-re-datastructures">String Representation of RE Datastructures</a></li>
+<li><a class="reference internal" href="#i"><code class="docutils literal notranslate"><span class="pre">I</span></code></a></li>
+<li><a class="reference internal" href="#id1"><code class="docutils literal notranslate"><span class="pre">(.111.)</span> <span class="pre">&</span> <span class="pre">(.01</span> <span class="pre">+</span> <span class="pre">11*)'</span></code></a></li>
+<li><a class="reference internal" href="#nully"><code class="docutils literal notranslate"><span class="pre">nully()</span></code></a></li>
+<li><a class="reference internal" href="#no-compaction">No “Compaction”</a></li>
+<li><a class="reference internal" href="#compaction-rules">Compaction Rules</a></li>
+<li><a class="reference internal" href="#memoizing">Memoizing</a></li>
+<li><a class="reference internal" href="#with-compaction">With “Compaction”</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#lets-try-it-out">Let’s try it out…</a></li>
+<li><a class="reference internal" href="#larger-alphabets">Larger Alphabets</a></li>
+<li><a class="reference internal" href="#state-machine">State Machine</a><ul>
+<li><a class="reference internal" href="#re-to-fsm">RE to FSM</a></li>
+<li><a class="reference internal" href="#explore"><code class="docutils literal notranslate"><span class="pre">explore()</span></code></a></li>
+<li><a class="reference internal" href="#generate-diagram">Generate Diagram</a></li>
+<li><a class="reference internal" href="#drive-a-fsm">Drive a FSM</a><ul>
+<li><a class="reference internal" href="#trampoline-function">Trampoline Function</a></li>
+<li><a class="reference internal" href="#stream-functions">Stream Functions</a></li>
+<li><a class="reference internal" href="#a-finite-state-machine">A Finite State Machine</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#reversing-the-derivatives-to-generate-matching-strings">Reversing the Derivatives to Generate Matching Strings</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Derivatives_of_Regular_Expressions.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Developing a Program in Joy — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Quadratic formula" href="Quadratic.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="developing-a-program-in-joy">
<div><p>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.</p>
<p>Find the sum of all the multiples of 3 or 5 below 1000.</p>
</div></blockquote>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<div class="section" id="sum-a-range-filtered-by-a-predicate">
<h3>Sum a range filtered by a predicate<a class="headerlink" href="#sum-a-range-filtered-by-a-predicate" title="Permalink to this headline">¶</a></h3>
<p>Let’s create a predicate that returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if a number is a multiple
of 3 or 5 and <code class="docutils literal notranslate"><span class="pre">False</span></code> otherwise.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == [3 % not] dupdip 5 % not or'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == [3 % not] dupdip 5 % not or'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'80 P'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'80 P'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">80</span> <span class="n">P</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">PE1</span><span class="o">.</span><span class="mi">1</span> <span class="o">==</span> <span class="o">+</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="n">dupdip</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1 == + [+] dupdip'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1 == + [+] dupdip'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 0 3 PE1.1'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 0 3 PE1.1'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">0</span> <span class="mi">0</span> <span class="mi">3</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">1</span>
<span class="mi">3</span> <span class="mi">3</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 0 [3 2 1 3 1 2 3] [PE1.1] step'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 0 [3 2 1 3 1 2 3] [PE1.1] step'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">0</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">step</span>
</div>
<div class="section" id="how-many-multiples-to-sum">
<h3>How many multiples to sum?<a class="headerlink" href="#how-many-multiples-to-sum" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="mi">1000</span> <span class="o">/</span> <span class="mi">15</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1000</span> <span class="o">/</span> <span class="mi">15</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">66</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="mi">66</span> <span class="o">*</span> <span class="mi">15</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">66</span> <span class="o">*</span> <span class="mi">15</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">990</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="mi">1000</span> <span class="o">-</span> <span class="mi">990</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1000</span> <span class="o">-</span> <span class="mi">990</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span>
</pre></div>
</div>
<p>We only want the terms <em>less than</em> 1000.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="mi">999</span> <span class="o">-</span> <span class="mi">990</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">999</span> <span class="o">-</span> <span class="mi">990</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">9</span>
</div>
<p>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.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1 == 0 0 66 [[3 2 1 3 1 2 3] [PE1.1] step] times [3 2 1 3] [PE1.1] step pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1 == 0 0 66 [[3 2 1 3 1 2 3] [PE1.1] step] times [3 2 1 3] [PE1.1] step pop'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">233168</span>
<span class="mi">0</span><span class="n">b</span> <span class="mi">11</span> <span class="mi">10</span> <span class="mi">01</span> <span class="mi">11</span> <span class="mi">01</span> <span class="mi">10</span> <span class="mi">11</span> <span class="o">==</span> <span class="mi">14811</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="mb">0b11100111011011</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mb">0b11100111011011</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">14811</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.2 == [3 & PE1.1] dupdip 2 >>'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.2 == [3 & PE1.1] dupdip 2 >>'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 0 14811 PE1.2'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 0 14811 PE1.2'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">0</span> <span class="mi">0</span> <span class="mi">14811</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">2</span>
<span class="mi">3</span> <span class="mi">3</span> <span class="mi">3702</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'3 3 3702 PE1.2'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'3 3 3702 PE1.2'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">3702</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">2</span>
<span class="mi">8</span> <span class="mi">5</span> <span class="mi">925</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 0 14811 7 [PE1.2] times pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'0 0 14811 7 [PE1.2] times pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">0</span> <span class="mi">0</span> <span class="mi">14811</span> <span class="mi">7</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mi">2</span><span class="p">]</span> <span class="n">times</span> <span class="n">pop</span>
</pre></div>
</div>
<p>And so we have at last:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1 == 0 0 66 [14811 7 [PE1.2] times pop] times 14811 4 [PE1.2] times popop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1 == 0 0 66 [14811 7 [PE1.2] times pop] times 14811 4 [PE1.2] times popop'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">233168</span>
<span class="n">n</span> <span class="mi">14811</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mi">2</span><span class="p">]</span> <span class="n">times</span> <span class="n">pop</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.3 == 14811 swap [PE1.2] times pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.3 == 14811 swap [PE1.2] times pop'</span><span class="p">)</span>
</pre></div>
</div>
<p>Now we can simplify the definition above:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">233168</span>
then four more. In the <em>Generator Programs</em> notebook we derive a
generator that can be repeatedly driven by the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator to
produce a stream of the seven numbers repeating over and over again.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.terms == [0 swap [dup [pop 14811] [] branch [3 &] dupdip 2 >>] dip rest cons]'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.terms == [0 swap [dup [pop 14811] [] branch [3 &] dupdip 2 >>] dip rest cons]'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1.terms 21 [x] times'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1.terms 21 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="p">[</span><span class="n">pop</span> <span class="mi">14811</span><span class="p">]</span> <span class="p">[]</span> <span class="n">branch</span> <span class="p">[</span><span class="mi">3</span> <span class="o">&</span><span class="p">]</span> <span class="n">dupdip</span> <span class="mi">2</span> <span class="o">>></span><span class="p">]</span> <span class="n">dip</span> <span class="n">rest</span> <span class="n">cons</span><span class="p">]</span>
</div>
<p>We know from above that we need sixty-six times seven then four more
terms to reach up to but not over one thousand.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'7 66 * 4 +'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'7 66 * 4 +'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">466</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1.terms 466 [x] times pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE1.terms 466 [x] times pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[PE1.terms 466 [x] times pop] run sum'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[PE1.terms 466 [x] times pop] run sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">999</span>
<p>Now we can use <code class="docutils literal notranslate"><span class="pre">PE1.1</span></code> to accumulate the terms as we go, and then
<code class="docutils literal notranslate"><span class="pre">pop</span></code> the generator and the counter from the stack when we’re done,
leaving just the sum.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 0 PE1.terms 466 [x [PE1.1] dip] times popop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 0 PE1.terms 466 [x [PE1.1] dip] times popop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">233168</span>
<h2>A little further analysis renders iteration unnecessary.<a class="headerlink" href="#a-little-further-analysis-renders-iteration-unnecessary" title="Permalink to this headline">¶</a></h2>
<p>Consider finding the sum of the positive integers less than or equal to
ten.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[10 9 8 7 6 5 4 3 2 1] sum'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[10 9 8 7 6 5 4 3 2 1] sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">55</span>
</div>
<p>(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.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'F == dup ++ * 2 floordiv'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'F == dup ++ * 2 floordiv'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'10 F'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'10 F'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">10</span> <span class="n">F</span>
</pre></div>
</div>
<p>If we reverse one of these two blocks and sum pairs…</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="mi">978</span> <span class="mi">15</span><span class="p">]</span> <span class="p">[</span><span class="mi">980</span> <span class="mi">12</span><span class="p">]</span> <span class="p">[</span><span class="mi">981</span> <span class="mi">10</span><span class="p">]</span> <span class="p">[</span><span class="mi">984</span> <span class="mi">9</span><span class="p">]</span> <span class="p">[</span><span class="mi">985</span> <span class="mi">6</span><span class="p">]</span> <span class="p">[</span><span class="mi">987</span> <span class="mi">5</span><span class="p">]</span> <span class="p">[</span><span class="mi">990</span> <span class="mi">3</span><span class="p">]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">993</span> <span class="mi">992</span> <span class="mi">991</span> <span class="mi">993</span> <span class="mi">991</span> <span class="mi">992</span> <span class="mi">993</span><span class="p">]</span>
</div>
<p>(Interesting that the sequence of seven numbers appears again in the
rightmost digit of each term.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[ 3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map sum'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[ 3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6945</span>
</div>
<p>So we can give the “sum of all the multiples of 3 or 5 below 1000” like
so:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'6945 33 * [993 995 996 999] cons sum'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'6945 33 * [993 995 996 999] cons sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">233168</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Developing a Program in Joy</a><ul>
+<li><a class="reference internal" href="#project-euler-first-problem-multiples-of-3-and-5">Project Euler, first problem: “Multiples of 3 and 5”</a><ul>
+<li><a class="reference internal" href="#sum-a-range-filtered-by-a-predicate">Sum a range filtered by a predicate</a></li>
+<li><a class="reference internal" href="#generate-just-the-multiples">Generate just the multiples</a></li>
+<li><a class="reference internal" href="#how-many-multiples-to-sum">How many multiples to sum?</a></li>
+<li><a class="reference internal" href="#packing-the-terms-into-an-integer">Packing the terms into an integer</a></li>
+<li><a class="reference internal" href="#let-s-refactor">Let’s refactor</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#generator-version">Generator Version</a></li>
+<li><a class="reference internal" href="#a-little-further-analysis-renders-iteration-unnecessary">A little further analysis renders iteration unnecessary.</a></li>
+<li><a class="reference internal" href="#the-simplest-program">The Simplest Program</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Developing.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Using x to Generate Values — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Newton’s method" href="Newton-Raphson.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="using-x-to-generate-values">
<h1>Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values<a class="headerlink" href="#using-x-to-generate-values" title="Permalink to this headline">¶</a></h1>
<p>Cf. jp-reprod.html</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<p>Consider the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator:</p>
</pre></div>
</div>
<p>Let’s try it:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] dip rest cons] x'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] dip rest cons] x'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">dip</span> <span class="n">rest</span> <span class="n">cons</span><span class="p">]</span> <span class="n">x</span>
</div>
<p>After one application of <code class="docutils literal notranslate"><span class="pre">x</span></code> the quoted program contains <code class="docutils literal notranslate"><span class="pre">1</span></code> and
<code class="docutils literal notranslate"><span class="pre">0</span></code> is below it on the stack.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] dip rest cons] x x x x x pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] dip rest cons] x x x x x pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span>
</div>
<div class="section" id="direco">
<h2><code class="docutils literal notranslate"><span class="pre">direco</span></code><a class="headerlink" href="#direco" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'direco == dip rest cons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'direco == dip rest cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] direco] x'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 swap [dup ++] direco] x'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span> <span class="n">x</span>
<span class="n">G</span> <span class="o">==</span> <span class="p">[</span><span class="n">direco</span><span class="p">]</span> <span class="n">cons</span> <span class="p">[</span><span class="n">swap</span><span class="p">]</span> <span class="n">swoncat</span> <span class="n">cons</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'G == [direco] cons [swap] swoncat cons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'G == [direco] cons [swap] swoncat cons'</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it out:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [dup ++] G'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [dup ++] G'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [dup ++] G x x x pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [dup ++] G x x x pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span>
</div>
<div class="section" id="powers-of-2">
<h3>Powers of 2<a class="headerlink" href="#powers-of-2" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 [dup 1 <<] G x x x x x x x x x pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'1 [dup 1 <<] G x x x x x x x x x pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">4</span> <span class="mi">8</span> <span class="mi">16</span> <span class="mi">32</span> <span class="mi">64</span> <span class="mi">128</span> <span class="mi">256</span>
<h3><code class="docutils literal notranslate"><span class="pre">[x]</span> <span class="pre">times</span></code><a class="headerlink" href="#x-times" title="Permalink to this headline">¶</a></h3>
<p>If we have one of these quoted programs we can drive it using <code class="docutils literal notranslate"><span class="pre">times</span></code>
with the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 [dup ++] G 5 [x] times'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 [dup ++] G 5 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span> <span class="mi">24</span> <span class="mi">25</span> <span class="mi">26</span> <span class="mi">27</span> <span class="p">[</span><span class="mi">28</span> <span class="n">swap</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</div>
<p>And pick them off by masking with 3 (binary 11) and then shifting the
int right two bits.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1 == dup [3 &] dip 2 >>'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1 == dup [3 &] dip 2 >>'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'14811 PE1.1'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'14811 PE1.1'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">14811</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">1</span>
</pre></div>
</div>
<p>If we plug <code class="docutils literal notranslate"><span class="pre">14811</span></code> and <code class="docutils literal notranslate"><span class="pre">[PE1.1]</span></code> into our generator form…</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'14811 [PE1.1] G'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'14811 [PE1.1] G'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">14811</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</pre></div>
</div>
-<p>…we get a generator that works for seven cycles before it reaches
-zero:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1] direco] 7 [x] times'</span><span class="p">)</span>
+<p>…we get a generator that works for seven cycles before it reaches zero:</p>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1] direco] 7 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
<h3>Reset at Zero<a class="headerlink" href="#reset-at-zero" title="Permalink to this headline">¶</a></h3>
<p>We need a function that checks if the int has reached zero and resets it
if so.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1.check == dup [pop 14811] [] branch'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.1.check == dup [pop 14811] [] branch'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'14811 [PE1.1.check PE1.1] G'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'14811 [PE1.1.check PE1.1] G'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">14811</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mf">1.</span><span class="n">check</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">0</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mf">1.</span><span class="n">check</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
<p>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.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'7 66 * 4 +'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'7 66 * 4 +'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">466</span>
</pre></div>
</div>
<p>If we drive our generator 466 times and sum the stack we get 999.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">3</span> <span class="p">[</span><span class="mi">57</span> <span class="n">swap</span> <span class="p">[</span><span class="n">PE1</span><span class="o">.</span><span class="mf">1.</span><span class="n">check</span> <span class="n">PE1</span><span class="o">.</span><span class="mi">1</span><span class="p">]</span> <span class="n">direco</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">999</span>
</div>
<div class="section" id="project-euler-problem-one">
<h2>Project Euler Problem One<a class="headerlink" href="#project-euler-problem-one" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.2 == + dup [+] dip'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE1.2 == + dup [+] dip'</span><span class="p">)</span>
</pre></div>
</div>
<p>Now we can add <code class="docutils literal notranslate"><span class="pre">PE1.2</span></code> to the quoted program given to <code class="docutils literal notranslate"><span class="pre">G</span></code>.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">233168</span>
<span class="n">fib_gen</span> <span class="o">==</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">1</span> <span class="n">F</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'fib == + [popdd over] cons infra uncons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'fib == + [popdd over] cons infra uncons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'fib_gen == [1 1 fib]'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'fib_gen == [1 1 fib]'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'fib_gen 10 [x] times'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'fib_gen 10 [x] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">5</span> <span class="mi">8</span> <span class="mi">13</span> <span class="mi">21</span> <span class="mi">34</span> <span class="mi">55</span> <span class="mi">89</span> <span class="p">[</span><span class="mi">144</span> <span class="mi">89</span> <span class="n">fib</span><span class="p">]</span>
<div class="section" id="project-euler-problem-two">
<h2>Project Euler Problem Two<a class="headerlink" href="#project-euler-problem-two" title="Permalink to this headline">¶</a></h2>
<blockquote>
-<div><p>By considering the terms in the Fibonacci sequence whose values do
-not exceed four million, find the sum of the even-valued terms.</p>
-</div></blockquote>
+<div>By considering the terms in the Fibonacci sequence whose values do
+not exceed four million, find the sum of the even-valued terms.</div></blockquote>
<p>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
<code class="docutils literal notranslate"><span class="pre">pop</span></code>s it otherwise.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2.1 == dup 2 % [+] [pop] branch'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2.1 == dup 2 % [+] [pop] branch'</span><span class="p">)</span>
</pre></div>
</div>
<p>And a predicate function that detects when the terms in the series
“exceed four million”.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'>4M == 4000000 >'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'>4M == 4000000 >'</span><span class="p">)</span>
</pre></div>
</div>
<p>Now it’s straightforward to define <code class="docutils literal notranslate"><span class="pre">PE2</span></code> as a recursive function that
generates terms in the Fibonacci sequence until they exceed four million
and sums the even ones.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE2'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'PE2'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">4613732</span>
</pre></div>
</div>
<p>Every third term is even.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] x x x'</span><span class="p">)</span> <span class="c1"># To start the sequence with 1 1 2 3 instead of 1 2 3.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] x x x'</span><span class="p">)</span> <span class="c1"># To start the sequence with 1 1 2 3 instead of 1 2 3.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span> <span class="mi">1</span> <span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="n">fib</span><span class="p">]</span>
</pre></div>
</div>
<p>Drive the generator three times and <code class="docutils literal notranslate"><span class="pre">popop</span></code> the two odd terms.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] x x x [popop] dipd'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] x x x [popop] dipd'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="n">fib</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2.2 == x x x [popop] dipd'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'PE2.2 == x x x [popop] dipd'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] 10 [PE2.2] times'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 0 fib] 10 [PE2.2] times'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="mi">8</span> <span class="mi">34</span> <span class="mi">144</span> <span class="mi">610</span> <span class="mi">2584</span> <span class="mi">10946</span> <span class="mi">46368</span> <span class="mi">196418</span> <span class="mi">832040</span> <span class="p">[</span><span class="mi">1346269</span> <span class="mi">832040</span> <span class="n">fib</span><span class="p">]</span>
</div>
<p>Replace <code class="docutils literal notranslate"><span class="pre">x</span></code> with our new driver function <code class="docutils literal notranslate"><span class="pre">PE2.2</span></code> and start our
<code class="docutils literal notranslate"><span class="pre">fib</span></code> generator at <code class="docutils literal notranslate"><span class="pre">1</span> <span class="pre">0</span></code>.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">4613732</span>
</div>
<div class="section" id="an-interesting-variation">
<h2>An Interesting Variation<a class="headerlink" href="#an-interesting-variation" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'codireco == cons dip rest cons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'codireco == cons dip rest cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 [dup ++] codireco] x'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[0 [dup ++] codireco] x'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">0</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="n">x</span>
<span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="o">++</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'G == [codireco] cons cons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'G == [codireco] cons cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'230 [dup ++] G 5 [x] times pop'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'230 [dup ++] G 5 [x] times pop'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">230</span> <span class="mi">231</span> <span class="mi">232</span> <span class="mi">233</span> <span class="mi">234</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a><ul>
+<li><a class="reference internal" href="#direco"><code class="docutils literal notranslate"><span class="pre">direco</span></code></a></li>
+<li><a class="reference internal" href="#making-generators">Making Generators</a><ul>
+<li><a class="reference internal" href="#powers-of-2">Powers of 2</a></li>
+<li><a class="reference internal" href="#x-times"><code class="docutils literal notranslate"><span class="pre">[x]</span> <span class="pre">times</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#generating-multiples-of-three-and-five">Generating Multiples of Three and Five</a><ul>
+<li><a class="reference internal" href="#reset-at-zero">Reset at Zero</a></li>
+<li><a class="reference internal" href="#run-466-times">Run 466 times</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#project-euler-problem-one">Project Euler Problem One</a></li>
+<li><a class="reference internal" href="#a-generator-for-the-fibonacci-sequence">A generator for the Fibonacci Sequence.</a></li>
+<li><a class="reference internal" href="#project-euler-problem-two">Project Euler Problem Two</a><ul>
+<li><a class="reference internal" href="#even-valued-fibonacci-terms">Even-valued Fibonacci Terms</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#how-to-compile-these">How to compile these?</a></li>
+<li><a class="reference internal" href="#an-interesting-variation">An Interesting Variation</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Generator_Programs.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Thun: Joy in Python — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Joy Interpreter" href="../joy.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="thun-joy-in-python">
model and method of Joy. Python seems like a great implementation
language for Joy for several reasons.</p>
<ul class="simple">
-<li><p>We can lean on the Python immutable types for our basic semantics and types: ints, floats, strings, and tuples, which enforces functional purity.</p></li>
-<li><p>We get garbage collection for free.</p></li>
-<li><p>Compilation via Cython.</p></li>
-<li><p>Python is a “glue language” with loads of libraries which we can wrap in Joy functions.</p></li>
+<li>We can lean on the Python immutable types for our basic semantics and types: ints, floats, strings, and tuples, which enforces functional purity.</li>
+<li>We get garbage collection for free.</li>
+<li>Compilation via Cython.</li>
+<li>Python is a “glue language” with loads of libraries which we can wrap in Joy functions.</li>
</ul>
<div class="section" id="read-eval-print-loop-repl">
<h2><a class="reference external" href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">Read-Eval-Print Loop (REPL)</a><a class="headerlink" href="#read-eval-print-loop-repl" title="Permalink to this headline">¶</a></h2>
<p>The main way to interact with the Joy interpreter is through a simple
<a class="reference external" href="https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">REPL</a>
that you start by running the package:</p>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ python -m joy
-Joypy - Copyright © 2017 Simon Forman
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ python3 -m joy
+Thun - Copyright © 2017 Simon Forman
This program comes with ABSOLUTELY NO WARRANTY; for details type "warranty".
This is free software, and you are welcome to redistribute it
under certain conditions; type "sharing" for details.
docs for a word.
- <-top
+<-top
joy? _
</pre></div>
You can enter Joy notation at the prompt and a <a class="reference internal" href="../pretty.html"><span class="doc">trace of evaluation</span></a> will
be printed followed by the stack and prompt again:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>joy? 23 sqr 18 +
- . 23 sqr 18 +
+
+547 <-top
+
+joy?
+</pre></div>
+</div>
+<p>There is a <cite>trace</cite> combinator:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>joy? 23 [sqr 18 +] trace
23 . sqr 18 +
23 . dup mul 18 +
23 23 . mul 18 +
</div>
<div class="section" id="examples">
<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'1 2 3 4 5'</span><span class="p">)</span> <span class="c1"># A simple sequence.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'1 2 3 4 5'</span><span class="p">)</span> <span class="c1"># A simple sequence.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="p">())))))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[1 2 3] 4 5'</span><span class="p">)</span> <span class="c1"># Three items, the first is a list with three items</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[1 2 3] 4 5'</span><span class="p">)</span> <span class="c1"># Three items, the first is a list with three items</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">()))),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="p">())))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'1 23 ["four" [-5.0] cons] 8888'</span><span class="p">)</span> <span class="c1"># A mixed bag. cons is</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'1 23 ["four" [-5.0] cons] 8888'</span><span class="p">)</span> <span class="c1"># A mixed bag. cons is</span>
<span class="c1"># a Symbol, no lookup at</span>
<span class="c1"># parse-time. Haiku docs.</span>
</pre></div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">23</span><span class="p">,</span> <span class="p">((</span><span class="s1">'four'</span><span class="p">,</span> <span class="p">((</span><span class="o">-</span><span class="mf">5.0</span><span class="p">,</span> <span class="p">()),</span> <span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="p">()))),</span> <span class="p">(</span><span class="mi">8888</span><span class="p">,</span> <span class="p">()))))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[][][][][]'</span><span class="p">)</span> <span class="c1"># Five empty lists.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[][][][][]'</span><span class="p">)</span> <span class="c1"># Five empty lists.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((),</span> <span class="p">((),</span> <span class="p">((),</span> <span class="p">((),</span> <span class="p">((),</span> <span class="p">())))))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[[[[[]]]]]'</span><span class="p">)</span> <span class="c1"># Five nested lists.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[[[[[]]]]]'</span><span class="p">)</span> <span class="c1"># Five nested lists.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((((((),</span> <span class="p">()),</span> <span class="p">()),</span> <span class="p">()),</span> <span class="p">()),</span> <span class="p">())</span>
<code class="docutils literal notranslate"><span class="pre">+</span></code>, the library module supports aliases), and combinators which
provide control-flow and higher-order operations.</p>
<p>Many of the functions are defined in Python, like <code class="docutils literal notranslate"><span class="pre">dip</span></code>:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">inspect</span><span class="o">.</span><span class="n">getsource</span><span class="p">(</span><span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">dip</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">inspect</span><span class="o">.</span><span class="n">getsource</span><span class="p">(</span><span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">dip</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">dip</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
When the interpreter executes a definition function that function just
pushes its body expression onto the pending expression (the
continuation) and returns control to the interpreter.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">definitions</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">definitions</span>
</pre></div>
</div>
-<pre class="literal-block">second == rest first
+<pre class="literal-block">
+second == rest first
third == rest rest first
product == 1 swap [*] step
swons == swap cons
range == [0 <=] [1 - dup] anamorphism
while == swap [nullary] cons dup dipd concat loop
dudipd == dup dipd
-primrec == [i] genrec</pre>
+primrec == [i] genrec
+</pre>
<p>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
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Thun: Joy in Python</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#read-eval-print-loop-repl">Read-Eval-Print Loop (REPL)</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#the-stack">The Stack</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#purely-functional-datastructures">Purely Functional Datastructures</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#the-joy-function">The <code class="docutils literal notranslate"><span class="pre">joy()</span></code> function</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#parser">Parser</a></li>
-<li class="toctree-l2"><a class="reference internal" href="#library">Library</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Thun: Joy in Python</a><ul>
+<li><a class="reference internal" href="#read-eval-print-loop-repl">Read-Eval-Print Loop (REPL)</a></li>
+<li><a class="reference internal" href="#the-stack">The Stack</a></li>
+<li><a class="reference internal" href="#purely-functional-datastructures">Purely Functional Datastructures</a></li>
+<li><a class="reference internal" href="#the-joy-function">The <code class="docutils literal notranslate"><span class="pre">joy()</span></code> function</a><ul>
+<li><a class="reference internal" href="#an-interpreter">An Interpreter</a></li>
+<li><a class="reference internal" href="#continuation-passing-style">Continuation-Passing Style</a></li>
+<li><a class="reference internal" href="#view-function">View function</a></li>
+<li><a class="reference internal" href="#the-traceprinter">The <code class="docutils literal notranslate"><span class="pre">TracePrinter</span></code>.</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#parser">Parser</a><ul>
+<li><a class="reference internal" href="#symbols">Symbols</a></li>
+<li><a class="reference internal" href="#token-regular-expressions">Token Regular Expressions</a></li>
+<li><a class="reference internal" href="#examples">Examples</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#library">Library</a><ul>
+<li><a class="reference internal" href="#there-should-be-only-one">“There should be only one.”</a></li>
+<li><a class="reference internal" href="#literary-code-library">Literary Code Library</a></li>
+</ul>
+</li>
</ul>
</li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="index.html">Essays about Programming in Joy</a></li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Intro.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Newton’s method — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Traversing Datastructures with Zippers" href="Zipper.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
- <div class="section" id="newton-s-method">
-<h1><a class="reference external" href="https://en.wikipedia.org/wiki/Newton%27s_method">Newton’s method</a><a class="headerlink" href="#newton-s-method" title="Permalink to this headline">¶</a></h1>
+ <div class="section" id="newtons-method">
+<h1><a class="reference external" href="https://en.wikipedia.org/wiki/Newton%27s_method">Newton’s method</a><a class="headerlink" href="#newtons-method" title="Permalink to this headline">¶</a></h1>
<p>Let’s use the Newton-Raphson method for finding the root of an equation
to write a function that can compute the square root of a number.</p>
<p>Cf. <a class="reference external" href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">“Why Functional Programming Matters” by John
Hughes</a></p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<div class="section" id="a-generator-for-approximations">
<span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="mi">23</span> <span class="n">over</span> <span class="o">/</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span><span class="p">]</span> <span class="n">make_generator</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="mi">23</span> <span class="n">over</span> <span class="o">/</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span>
</div>
<p>Let’s drive the generator a few time (with the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator) and
square the approximation to see how well it works…</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra 6 [x popd] times first sqr'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra 6 [x popd] times first sqr'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">23.0000000001585</span>
<p>From <a class="reference external" href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">“Why Functional Programming Matters” by John
Hughes</a>:</p>
<blockquote>
-<div><p>The remainder of a square root finder is a function <em>within</em>, which
+<div>The remainder of a square root finder is a function <em>within</em>, which
takes a tolerance and a list of approximations and looks down the
list for two successive approximations that differ by no more than
-the given tolerance.</p>
-</div></blockquote>
+the given tolerance.</div></blockquote>
<p>(And note that by “list” he means a lazily-evaluated list.)</p>
<p>Using the <em>output</em> <code class="docutils literal notranslate"><span class="pre">[a</span> <span class="pre">G]</span></code> of the above generator for square root
approximations, and further assuming that the first term a has been
<span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">a</span><span class="o">-</span><span class="n">b</span><span class="p">)</span><span class="o"><=</span><span class="n">ε</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_P == [first - abs] dip <='</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_P == [first - abs] dip <='</span><span class="p">)</span>
</pre></div>
</div>
</div>
<span class="n">b</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_B == roll< popop first'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_B == roll< popop first'</span><span class="p">)</span>
</pre></div>
</div>
</div>
</pre></div>
</div>
<ol class="arabic simple">
-<li><p>Discard a.</p></li>
-<li><p>Use <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator to generate next term from <code class="docutils literal notranslate"><span class="pre">G</span></code>.</p></li>
-<li><p>Run <code class="docutils literal notranslate"><span class="pre">within</span></code> with <code class="docutils literal notranslate"><span class="pre">i</span></code> (it is a <code class="docutils literal notranslate"><span class="pre">primrec</span></code> function.)</p></li>
+<li>Discard a.</li>
+<li>Use <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator to generate next term from <code class="docutils literal notranslate"><span class="pre">G</span></code>.</li>
+<li>Run <code class="docutils literal notranslate"><span class="pre">within</span></code> with <code class="docutils literal notranslate"><span class="pre">i</span></code> (it is a <code class="docutils literal notranslate"><span class="pre">primrec</span></code> function.)</li>
</ol>
<p>Pretty straightforward:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">R0</span> <span class="p">[</span><span class="n">within</span><span class="p">]</span> <span class="n">R1</span>
<span class="n">b</span> <span class="p">[</span><span class="n">c</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">within</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_R == [popd x] dip'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_R == [popd x] dip'</span><span class="p">)</span>
</pre></div>
</div>
</div>
<span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="o">...</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec'</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">'sqrt == gsra within'</span><span class="p">)</span>
</pre></div>
</div>
<p>Try it out…</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'36 sqrt'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'36 sqrt'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">6.0</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqrt'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqrt'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span>
</pre></div>
</div>
<p>Check it.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span><span class="o">**</span><span class="mi">2</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span><span class="o">**</span><span class="mi">2</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">22.999999999999996</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">sqrt</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">math</span> <span class="k">import</span> <span class="n">sqrt</span>
<span class="n">sqrt</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span>
</pre></div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Newton’s method</a><ul>
+<li><a class="reference internal" href="#a-generator-for-approximations">A Generator for Approximations</a><ul>
+<li><a class="reference internal" href="#a-function-to-compute-the-next-approximation">A Function to Compute the Next Approximation</a></li>
+<li><a class="reference internal" href="#make-it-into-a-generator">Make it into a Generator</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#finding-consecutive-approximations-within-a-tolerance">Finding Consecutive Approximations within a Tolerance</a><ul>
+<li><a class="reference internal" href="#predicate">Predicate</a></li>
+<li><a class="reference internal" href="#base-case">Base-Case</a></li>
+<li><a class="reference internal" href="#recur">Recur</a></li>
+<li><a class="reference internal" href="#setting-up">Setting up</a></li>
+</ul>
+</li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Newton-Raphson.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>No Updates — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Categorical Programming" href="Categorical.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="no-updates">
<h1>No Updates<a class="headerlink" href="#no-updates" title="Permalink to this headline">¶</a></h1>
<p>DRAFT</p>
<ol class="arabic simple">
-<li><p>Joy doesn’t need to change.</p></li>
+<li>Joy doesn’t need to change.</li>
</ol>
<blockquote>
<div><ol class="upperalpha simple">
-<li><p>The interpreter doesn’t need to change, <code class="docutils literal notranslate"><span class="pre">viewer</span></code> function can customize mainloop. Or use a sub-interpreter (Joy in Joy.) The base interpreter remains static.</p></li>
-<li><p>Once a function has been named and defined <em>never change that name</em>. It’s just not allowed. If you need to change a function <code class="docutils literal notranslate"><span class="pre">foo</span></code> you have to call it <code class="docutils literal notranslate"><span class="pre">foo_II</span></code> or something. Once a function (name mapped to behavior) is released to the public <em>that’s it</em>, it’s done.</p></li>
-<li><p>The language evolves by adding new definitions and refactoring, always choosing new names for new functions.</p></li>
+<li>The interpreter doesn’t need to change, <code class="docutils literal notranslate"><span class="pre">viewer</span></code> function can customize mainloop. Or use a sub-interpreter (Joy in Joy.) The base interpreter remains static.</li>
+<li>Once a function has been named and defined <em>never change that name</em>. It’s just not allowed. If you need to change a function <code class="docutils literal notranslate"><span class="pre">foo</span></code> you have to call it <code class="docutils literal notranslate"><span class="pre">foo_II</span></code> or something. Once a function (name mapped to behavior) is released to the public <em>that’s it</em>, it’s done.</li>
+<li>The language evolves by adding new definitions and refactoring, always choosing new names for new functions.</li>
</ol>
</div></blockquote>
<ol class="arabic simple" start="2">
-<li><p>Following <a class="reference external" href="https://semver.org">Semantic Versioning</a> there will never be a version 2.0.</p></li>
+<li>Following <a class="reference external" href="https://semver.org">Semantic Versioning</a> there will never be a version 2.0.</li>
</ol>
<blockquote>
<div><ol class="upperalpha simple">
-<li><p><a class="reference external" href="https://semver.org/#spec-item-8">Major version must be incremented if any backwards incompatible changes are introduced to the public API.</a></p></li>
-<li><p>We never implement any backwards incompatible changes, so…</p></li>
-<li><p>We could see e.g. Thun version 1.273.3!</p></li>
+<li><a class="reference external" href="https://semver.org/#spec-item-8">Major version must be incremented if any backwards incompatible changes are introduced to the public API.</a></li>
+<li>We never implement any backwards incompatible changes, so…</li>
+<li>We could see e.g. Thun version 1.273.3!</li>
</ol>
</div></blockquote>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
-</ul>
-</li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/NoUpdates.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Treating Trees I: Ordered Binary Trees — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Treating Trees II: treestep" href="Treestep.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="treating-trees-i-ordered-binary-trees">
implementation under the hood. (Where does the “type” come from? It has
a contingent existence predicated on the disciplined use of these
functions on otherwise undistinguished Joy datastructures.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span><span class="p">,</span> <span class="n">DefinitionWrapper</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span><span class="p">,</span> <span class="n">DefinitionWrapper</span>
</pre></div>
</div>
<div class="section" id="adding-nodes-to-the-tree">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Tree</span><span class="o">-</span><span class="n">new</span> <span class="o">==</span> <span class="n">swap</span> <span class="p">[[]</span> <span class="p">[]]</span> <span class="n">cons</span> <span class="n">cons</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-new == swap [[] []] cons cons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-new == swap [[] []] cons cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'"v" "k" Tree-new'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'"v" "k" Tree-new'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'k'</span> <span class="s1">'v'</span> <span class="p">[]</span> <span class="p">[]]</span>
<span class="n">P</span> <span class="o">==</span> <span class="n">pop</span> <span class="n">roll</span><span class="o">></span> <span class="n">pop</span> <span class="n">first</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == pop roll> pop first'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == pop roll> pop first'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_key" 23 [] []] 17 "new_key" ["..."] P'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_key" 23 [] []] 17 "new_key" ["..."] P'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'new_key'</span> <span class="s1">'old_key'</span>
</pre></div>
</div>
</div>
-<div class="section" id="if-the-key-we-re-adding-is-greater-than-the-node-s-key">
-<h4>If the key we’re adding is greater than the node’s key.<a class="headerlink" href="#if-the-key-we-re-adding-is-greater-than-the-node-s-key" title="Permalink to this headline">¶</a></h4>
+<div class="section" id="if-the-key-were-adding-is-greater-than-the-nodes-key">
+<h4>If the key we’re adding is greater than the node’s key.<a class="headerlink" href="#if-the-key-were-adding-is-greater-than-the-nodes-key" title="Permalink to this headline">¶</a></h4>
<p>Here the parentheses are meant to signify that the expression is not
literal, the code in the parentheses is meant to have been evaluated:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="n">key_n</span> <span class="n">value_n</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="n">value</span> <span class="n">key</span> <span class="p">[</span><span class="n">Tree</span><span class="o">-</span><span class="n">add</span><span class="p">]</span> <span class="n">T</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">T</span> <span class="o">==</span> <span class="n">cons</span> <span class="n">cons</span> <span class="p">[</span><span class="n">dipdd</span><span class="p">]</span> <span class="n">cons</span> <span class="n">infra</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'T == cons cons [dipdd] cons infra'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'T == cons cons [dipdd] cons infra'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] T'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] T'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'old_k'</span> <span class="s1">'old_value'</span> <span class="s1">'left'</span> <span class="s1">'Tree-add'</span> <span class="s1">'new_key'</span> <span class="s1">'new_value'</span> <span class="s1">'right'</span><span class="p">]</span>
</pre></div>
</div>
</div>
-<div class="section" id="if-the-key-we-re-adding-is-less-than-the-node-s-key">
-<h4>If the key we’re adding is less than the node’s key.<a class="headerlink" href="#if-the-key-we-re-adding-is-less-than-the-node-s-key" title="Permalink to this headline">¶</a></h4>
+<div class="section" id="if-the-key-were-adding-is-less-than-the-nodes-key">
+<h4>If the key we’re adding is less than the node’s key.<a class="headerlink" href="#if-the-key-were-adding-is-less-than-the-nodes-key" title="Permalink to this headline">¶</a></h4>
<p>This is very very similar to the above:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">key_n</span> <span class="n">value_n</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="n">value</span> <span class="n">key</span> <span class="p">[</span><span class="n">Tree</span><span class="o">-</span><span class="n">add</span><span class="p">]</span> <span class="n">E</span>
<span class="p">[</span><span class="n">key_n</span> <span class="n">value_n</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="n">value</span> <span class="n">key</span> <span class="p">[</span><span class="n">Tree</span><span class="o">-</span><span class="n">add</span><span class="p">]</span> <span class="p">[</span><span class="n">P</span> <span class="o"><</span><span class="p">]</span> <span class="p">[</span><span class="n">Te</span><span class="p">]</span> <span class="p">[</span><span class="n">Ee</span><span class="p">]</span> <span class="n">ifte</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'E == [P <] [Te] [Ee] ifte'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'E == [P <] [Te] [Ee] ifte'</span><span class="p">)</span>
</pre></div>
</div>
<p>In this case <code class="docutils literal notranslate"><span class="pre">Te</span></code> works that same as <code class="docutils literal notranslate"><span class="pre">T</span></code> but on the left child tree
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Te</span> <span class="o">==</span> <span class="n">cons</span> <span class="n">cons</span> <span class="p">[</span><span class="n">dipd</span><span class="p">]</span> <span class="n">cons</span> <span class="n">infra</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Te == cons cons [dipd] cons infra'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Te == cons cons [dipd] cons infra'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] Te'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] Te'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'old_k'</span> <span class="s1">'old_value'</span> <span class="s1">'Tree-add'</span> <span class="s1">'new_key'</span> <span class="s1">'new_value'</span> <span class="s1">'left'</span> <span class="s1">'right'</span><span class="p">]</span>
<span class="p">[</span><span class="n">key</span> <span class="n">new_value</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Ee == pop swap roll< rest rest cons cons'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Ee == pop swap roll< rest rest cons cons'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["k" "old_value" "left" "right"] "new_value" "k" ["Tree-add"] Ee'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["k" "old_value" "left" "right"] "new_value" "k" ["Tree-add"] Ee'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'k'</span> <span class="s1">'new_value'</span> <span class="s1">'left'</span> <span class="s1">'right'</span><span class="p">]</span>
<span class="n">Tree</span><span class="o">-</span><span class="n">add</span> <span class="o">==</span> <span class="p">[</span><span class="n">popop</span> <span class="ow">not</span><span class="p">]</span> <span class="p">[[</span><span class="n">pop</span><span class="p">]</span> <span class="n">dipd</span> <span class="n">Tree</span><span class="o">-</span><span class="n">new</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="n">R</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec'</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="examples">
<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Initial</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Initial</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Greater than</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Greater than</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "a" Tree-add'</span><span class="p">)</span> <span class="c1"># Less than</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "a" Tree-add'</span><span class="p">)</span> <span class="c1"># Less than</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Equal to</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Equal to</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Series.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Series.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
<span class="n">L</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 0 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 0 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'G'</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'E'</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"0 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"0 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'L'</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">P</span> <span class="o">==</span> <span class="n">over</span> <span class="p">[</span><span class="n">popop</span> <span class="n">popop</span> <span class="n">first</span><span class="p">]</span> <span class="n">nullary</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == over [popop popop first] nullary'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == over [popop popop first] nullary'</span><span class="p">)</span>
</pre></div>
</div>
<p>Using <code class="docutils literal notranslate"><span class="pre">cmp</span></code> to simplify <cite>our code above at
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Tree</span><span class="o">-</span><span class="n">add</span> <span class="o">==</span> <span class="p">[</span><span class="n">popop</span> <span class="ow">not</span><span class="p">]</span> <span class="p">[[</span><span class="n">pop</span><span class="p">]</span> <span class="n">dipd</span> <span class="n">Tree</span><span class="o">-</span><span class="n">new</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="p">]</span> <span class="p">[</span><span class="n">Ee</span><span class="p">]</span> <span class="p">[</span><span class="n">Te</span><span class="p">]</span> <span class="nb">cmp</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Still works.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Still works.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Tree</span><span class="o">-</span><span class="nb">iter</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="n">roll</span><span class="o"><</span> <span class="p">[</span><span class="n">dupdip</span> <span class="n">rest</span> <span class="n">rest</span><span class="p">]</span> <span class="n">cons</span> <span class="p">[</span><span class="n">step</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec'</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="id1">
<h3>Examples<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [foo] Tree-iter'</span><span class="p">)</span> <span class="c1"># It doesn't matter what F is as it won't be used.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [foo] Tree-iter'</span><span class="p">)</span> <span class="c1"># It doesn't matter what F is as it won't be used.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter"</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'b'</span> <span class="s1">'a'</span> <span class="s1">'c'</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter"</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter"</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span> <span class="mi">88</span> <span class="mi">44</span>
<div class="section" id="interlude-a-set-like-datastructure">
<h2>Interlude: A Set-like Datastructure<a class="headerlink" href="#interlude-a-set-like-datastructure" title="Permalink to this headline">¶</a></h2>
<p>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 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
<cite>:math:`O(log_2 N)</cite> <<a class="reference external" href="https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2">https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2</a>>`__
time.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'to_set == [] swap [0 swap Tree-add] step'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'to_set == [] swap [0 swap Tree-add] step'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
</div>
<p>And with that we can write a little program <code class="docutils literal notranslate"><span class="pre">unique</span></code> to remove
duplicate items from a list.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'unique == [to_set [first] Tree-iter] cons run'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'unique == [to_set [first] Tree-iter] cons run'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique'</span><span class="p">)</span> <span class="c1"># Filter duplicate items.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique'</span><span class="p">)</span> <span class="c1"># Filter duplicate items.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">7</span> <span class="mi">6</span> <span class="mi">8</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">9</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">]</span>
</pre></div>
</div>
<p>If <code class="docutils literal notranslate"><span class="pre">F</span></code> needs items from the stack below the left stuff it should have
-<code class="docutils literal notranslate"><span class="pre">cons</span></code>’d them before beginning maybe? For functions like <code class="docutils literal notranslate"><span class="pre">first</span></code> it
-works fine as-is.</p>
+<code class="docutils literal notranslate"><span class="pre">cons</span></code>’d them before beginning maybe? For functions like <code class="docutils literal notranslate"><span class="pre">first</span></code>
+it works fine as-is.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">left</span> <span class="n">Tree</span><span class="o">-</span><span class="nb">iter</span><span class="o">-</span><span class="n">order</span> <span class="p">[</span><span class="n">key</span> <span class="n">value</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="n">first</span> <span class="p">[</span><span class="n">key</span> <span class="n">value</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">Tree</span><span class="o">-</span><span class="nb">iter</span><span class="o">-</span><span class="n">order</span><span class="p">]</span>
<span class="n">left</span> <span class="n">Tree</span><span class="o">-</span><span class="nb">iter</span><span class="o">-</span><span class="n">order</span> <span class="n">key</span> <span class="p">[</span><span class="n">key</span> <span class="n">value</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">Tree</span><span class="o">-</span><span class="nb">iter</span><span class="o">-</span><span class="n">order</span><span class="p">]</span>
</pre></div>
</pre></div>
</div>
<p>Now we can sort sequences.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1">#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')</span>
<span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span>
<span class="n">Tree</span><span class="o">-</span><span class="n">get</span> <span class="o">==</span> <span class="p">[</span><span class="n">pop</span> <span class="ow">not</span><span class="p">]</span> <span class="n">swap</span> <span class="p">[]</span> <span class="p">[</span><span class="n">P</span> <span class="p">[</span><span class="n">T</span><span class="o">></span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o"><</span><span class="p">]</span> <span class="nb">cmp</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># I don't want to deal with name conflicts with the above so I'm inlining everything here.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># I don't want to deal with name conflicts with the above so I'm inlining everything here.</span>
<span class="c1"># The original Joy system has "hide" which is a meta-command which allows you to use named</span>
<span class="c1"># definitions that are only in scope for a given definition. I don't want to implement</span>
<span class="c1"># that (yet) so...</span>
<span class="s1">'''</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'mike not in tree'</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "gary" [popop "err"] Tree-get'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "gary" [popop "err"] Tree-get'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1"> [] [[0 'a'] [1 'b'] [2 'c']] [i Tree-add] step</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1"> [] [[0 'a'] [1 'b'] [2 'c']] [i Tree-add] step</span>
</div>
<p>By the standards of the code I’ve written so far, this is a <em>huge</em> Joy
program.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1">first_two == uncons uncons pop</span>
<span class="s1">fourth == rest rest rest first</span>
<span class="s1">?fourth == [] [fourth] [] ifte</span>
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete "</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'a'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete "</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'a'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete "</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete "</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'a'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete "</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete "</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete "</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]]</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Treating Trees I: Ordered Binary Trees</a><ul>
+<li><a class="reference internal" href="#adding-nodes-to-the-tree">Adding Nodes to the Tree</a><ul>
+<li><a class="reference internal" href="#adding-to-an-empty-node">Adding to an empty node.</a><ul>
+<li><a class="reference internal" href="#tree-new"><code class="docutils literal notranslate"><span class="pre">Tree-new</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#adding-to-a-non-empty-node">Adding to a non-empty node.</a><ul>
+<li><a class="reference internal" href="#a-predicate-to-compare-keys">A predicate to compare keys.</a></li>
+<li><a class="reference internal" href="#if-the-key-were-adding-is-greater-than-the-nodes-key">If the key we’re adding is greater than the node’s key.</a></li>
+<li><a class="reference internal" href="#if-the-key-were-adding-is-less-than-the-nodes-key">If the key we’re adding is less than the node’s key.</a></li>
+<li><a class="reference internal" href="#else-the-keys-must-be-equal">Else the keys must be equal.</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#now-we-can-define-tree-add">Now we can define <code class="docutils literal notranslate"><span class="pre">Tree-add</span></code></a></li>
+<li><a class="reference internal" href="#examples">Examples</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#interlude-cmp-combinator">Interlude: <code class="docutils literal notranslate"><span class="pre">cmp</span></code> combinator</a><ul>
+<li><a class="reference internal" href="#redefine-tree-add">Redefine <code class="docutils literal notranslate"><span class="pre">Tree-add</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#a-function-to-traverse-this-structure">A Function to Traverse this Structure</a><ul>
+<li><a class="reference internal" href="#base-case">Base case <code class="docutils literal notranslate"><span class="pre">[]</span></code></a></li>
+<li><a class="reference internal" href="#node-case-key-value-left-right">Node case <code class="docutils literal notranslate"><span class="pre">[key</span> <span class="pre">value</span> <span class="pre">left</span> <span class="pre">right]</span></code></a><ul>
+<li><a class="reference internal" href="#processing-the-current-node">Processing the current node.</a></li>
+<li><a class="reference internal" href="#recur">Recur</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#putting-it-together">Putting it together</a></li>
+<li><a class="reference internal" href="#parameterizing-the-f-per-node-processing-function">Parameterizing the <code class="docutils literal notranslate"><span class="pre">F</span></code> per-node processing function.</a></li>
+<li><a class="reference internal" href="#tree-iter"><code class="docutils literal notranslate"><span class="pre">Tree-iter</span></code></a></li>
+<li><a class="reference internal" href="#id1">Examples</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#interlude-a-set-like-datastructure">Interlude: A Set-like Datastructure</a></li>
+<li><a class="reference internal" href="#a-version-of-tree-iter-that-does-in-order-traversal">A Version of <code class="docutils literal notranslate"><span class="pre">Tree-iter</span></code> that does In-Order Traversal</a><ul>
+<li><a class="reference internal" href="#process-the-left-child">Process the left child.</a></li>
+<li><a class="reference internal" href="#process-the-current-node">Process the current node.</a></li>
+<li><a class="reference internal" href="#process-the-right-child">Process the right child.</a></li>
+<li><a class="reference internal" href="#defining-tree-iter-order">Defining <code class="docutils literal notranslate"><span class="pre">Tree-iter-order</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#getting-values-by-key">Getting values by key</a><ul>
+<li><a class="reference internal" href="#the-base-case">The base case <code class="docutils literal notranslate"><span class="pre">[]</span></code></a></li>
+<li><a class="reference internal" href="#id2">Node case <code class="docutils literal notranslate"><span class="pre">[key</span> <span class="pre">value</span> <span class="pre">left</span> <span class="pre">right]</span></code></a><ul>
+<li><a class="reference internal" href="#predicate">Predicate</a></li>
+<li><a class="reference internal" href="#branches">Branches</a></li>
+<li><a class="reference internal" href="#greater-than-and-less-than">Greater than and less than</a></li>
+<li><a class="reference internal" href="#equal-keys">Equal keys</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#tree-get"><code class="docutils literal notranslate"><span class="pre">Tree-get</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#tree-delete">Tree-delete</a><ul>
+<li><a class="reference internal" href="#id3">Base case</a></li>
+<li><a class="reference internal" href="#id4">Recur</a></li>
+<li><a class="reference internal" href="#compare-keys">Compare Keys</a></li>
+<li><a class="reference internal" href="#greater-than-case-and-less-than-case">Greater than case and less than case</a></li>
+<li><a class="reference internal" href="#the-else-case">The else case</a><ul>
+<li><a class="reference internal" href="#one-or-more-child-nodes-are">One or more child nodes are <code class="docutils literal notranslate"><span class="pre">[]</span></code></a></li>
+<li><a class="reference internal" href="#both-child-nodes-are-non-empty">Both child nodes are non-empty.</a></li>
+<li><a class="reference internal" href="#we-have-to-we-find-the-highest-right-most-node-in-our-lower-left-sub-tree">We have to we find the highest (right-most) node in our lower (left) sub-tree:</a></li>
+<li><a class="reference internal" href="#found-right-most-node-in-our-left-sub-tree">Found right-most node in our left sub-tree</a></li>
+<li><a class="reference internal" href="#replace-current-node-key-and-value-recursively-delete-rightmost">Replace current node key and value, recursively delete rightmost</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#refactoring">Refactoring</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#appendix-the-source-code">Appendix: The source code.</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Ordered_Binary_Trees.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Quadratic formula — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Replacing Functions in the Dictionary" href="Replacing.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
- <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+ <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<div class="section" id="quadratic-formula">
</div>
<p>The three arguments are to the left, so we can “chop off” everything to
the right and say it’s the definition of the <code class="docutils literal notranslate"><span class="pre">quadratic</span></code> function:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2'</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it out:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 1 1 quadratic'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 1 1 quadratic'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mf">0.3819660112501051</span> <span class="o">-</span><span class="mf">2.618033988749895</span>
lines are the <code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">dipd</span></code> combinators building the main program
by incorporating the values on the stack. Then that program runs and you
get the results. This is pretty typical of Joy code.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'-5 1 4 quadratic'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'-5 1 4 quadratic'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="o">-</span><span class="mi">5</span> <span class="mi">1</span> <span class="mi">4</span> <span class="n">quadratic</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Quadratic formula</a><ul>
+<li><a class="reference internal" href="#write-a-straightforward-program-with-variable-names">Write a straightforward program with variable names.</a><ul>
+<li><a class="reference internal" href="#b"><code class="docutils literal notranslate"><span class="pre">-b</span></code></a></li>
+<li><a class="reference internal" href="#sqrt-b-2-4-a-c"><code class="docutils literal notranslate"><span class="pre">sqrt(b^2</span> <span class="pre">-</span> <span class="pre">4</span> <span class="pre">*</span> <span class="pre">a</span> <span class="pre">*</span> <span class="pre">c)</span></code></a></li>
+<li><a class="reference internal" href="#a"><code class="docutils literal notranslate"><span class="pre">/2a</span></code></a></li>
+<li><a class="reference internal" href="#id1"><code class="docutils literal notranslate"><span class="pre">±</span></code></a></li>
+<li><a class="reference internal" href="#putting-them-together">Putting Them Together</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#derive-a-definition">Derive a definition.</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Quadratic.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Recursion Combinators — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Treating Trees I: Ordered Binary Trees" href="Ordered_Binary_Trees.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
- <div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">DefinitionWrapper</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+ <div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">DefinitionWrapper</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<div class="section" id="recursion-combinators">
</div>
<p>From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun:</p>
<blockquote>
-<div><p>“The genrec combinator takes four program parameters in addition to
-whatever data parameters it needs. Fourth from the top is an
-if-part, followed by a then-part. If the if-part yields true, then
-the then-part is executed and the combinator terminates. The other
-two 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.”</p>
-</div></blockquote>
+<div>“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.”</div></blockquote>
<div class="section" id="designing-recursive-functions">
<h2>Designing Recursive Functions<a class="headerlink" href="#designing-recursive-functions" title="Permalink to this headline">¶</a></h2>
<p>The way to design one of these is to fix your base case and test and
is a recursive function <code class="docutils literal notranslate"><span class="pre">H</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-></span> <span class="pre">C</span></code> that converts a value of type
<code class="docutils literal notranslate"><span class="pre">A</span></code> into a value of type <code class="docutils literal notranslate"><span class="pre">C</span></code> by means of:</p>
<ul class="simple">
-<li><p>A generator <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-></span> <span class="pre">(B,</span> <span class="pre">A)</span></code></p></li>
-<li><p>A combiner <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">::</span> <span class="pre">(B,</span> <span class="pre">C)</span> <span class="pre">-></span> <span class="pre">C</span></code></p></li>
-<li><p>A predicate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-></span> <span class="pre">Bool</span></code> to detect the base case</p></li>
-<li><p>A base case value <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">::</span> <span class="pre">C</span></code></p></li>
-<li><p>Recursive calls (zero or more); it has a “call stack in the form of a
-cons list”.</p></li>
+<li>A generator <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-></span> <span class="pre">(B,</span> <span class="pre">A)</span></code></li>
+<li>A combiner <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">::</span> <span class="pre">(B,</span> <span class="pre">C)</span> <span class="pre">-></span> <span class="pre">C</span></code></li>
+<li>A predicate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-></span> <span class="pre">Bool</span></code> to detect the base case</li>
+<li>A base case value <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">::</span> <span class="pre">C</span></code></li>
+<li>Recursive calls (zero or more); it has a “call stack in the form of a
+cons list”.</li>
</ul>
<p>It may be helpful to see this function implemented in imperative Python
code.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hylomorphism</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hylomorphism</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
<span class="sd">'''Return a hylomorphism function H.'''</span>
<span class="k">def</span> <span class="nf">H</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
</div>
<p>Working in reverse:</p>
<ul class="simple">
-<li><p>Use <code class="docutils literal notranslate"><span class="pre">swoncat</span></code> twice to decouple <code class="docutils literal notranslate"><span class="pre">[c]</span></code> and <code class="docutils literal notranslate"><span class="pre">[F]</span></code>.</p></li>
-<li><p>Use <code class="docutils literal notranslate"><span class="pre">unit</span></code> to dequote <code class="docutils literal notranslate"><span class="pre">c</span></code>.</p></li>
-<li><p>Use <code class="docutils literal notranslate"><span class="pre">dipd</span></code> to untangle <code class="docutils literal notranslate"><span class="pre">[unit</span> <span class="pre">[pop]</span> <span class="pre">swoncat]</span></code> from the givens.</p></li>
+<li>Use <code class="docutils literal notranslate"><span class="pre">swoncat</span></code> twice to decouple <code class="docutils literal notranslate"><span class="pre">[c]</span></code> and <code class="docutils literal notranslate"><span class="pre">[F]</span></code>.</li>
+<li>Use <code class="docutils literal notranslate"><span class="pre">unit</span></code> to dequote <code class="docutils literal notranslate"><span class="pre">c</span></code>.</li>
+<li>Use <code class="docutils literal notranslate"><span class="pre">dipd</span></code> to untangle <code class="docutils literal notranslate"><span class="pre">[unit</span> <span class="pre">[pop]</span> <span class="pre">swoncat]</span></code> from the givens.</li>
</ul>
<p>So:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">H</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="n">c</span><span class="p">]</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">F</span><span class="p">]</span> <span class="n">genrec</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">hylomorphism</span> <span class="o">==</span> <span class="p">[</span><span class="n">unit</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="n">swoncat</span><span class="p">]</span> <span class="n">dipd</span> <span class="p">[</span><span class="n">dip</span><span class="p">]</span> <span class="n">swoncat</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec'</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="example-finding-triangular-numbers">
<code class="docutils literal notranslate"><span class="pre">A</span></code>, <code class="docutils literal notranslate"><span class="pre">B</span></code> and <code class="docutils literal notranslate"><span class="pre">C</span></code> are all <code class="docutils literal notranslate"><span class="pre">int</span></code>.)</p>
<p>To sum a range of integers from 0 to <em>n</em> - 1:</p>
<ul class="simple">
-<li><p><code class="docutils literal notranslate"><span class="pre">[P]</span></code> is <code class="docutils literal notranslate"><span class="pre">[1</span> <span class="pre"><=]</span></code></p></li>
-<li><p><code class="docutils literal notranslate"><span class="pre">c</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code></p></li>
-<li><p><code class="docutils literal notranslate"><span class="pre">[G]</span></code> is <code class="docutils literal notranslate"><span class="pre">[--</span> <span class="pre">dup]</span></code></p></li>
-<li><p><code class="docutils literal notranslate"><span class="pre">[F]</span></code> is <code class="docutils literal notranslate"><span class="pre">[+]</span></code></p></li>
+<li><code class="docutils literal notranslate"><span class="pre">[P]</span></code> is <code class="docutils literal notranslate"><span class="pre">[1</span> <span class="pre"><=]</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">c</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">[G]</span></code> is <code class="docutils literal notranslate"><span class="pre">[--</span> <span class="pre">dup]</span></code></li>
+<li><code class="docutils literal notranslate"><span class="pre">[F]</span></code> is <code class="docutils literal notranslate"><span class="pre">[+]</span></code></li>
</ul>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism'</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 triangular_number'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 triangular_number'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 1 2 3 4 5 6] [triangular_number] map'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 1 2 3 4 5 6] [triangular_number] map'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">6</span> <span class="mi">10</span> <span class="mi">15</span><span class="p">]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
-<div class="section" id="range-et-al">
-<h3><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al.<a class="headerlink" href="#range-et-al" title="Permalink to this headline">¶</a></h3>
-<p>An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates
-the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</p>
+<div class="section" id="range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n">
+<h3><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al. An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.<a class="headerlink" href="#range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n" title="Permalink to this headline">¶</a></h3>
<p>Each of the above variations can be used to make four slightly different
<code class="docutils literal notranslate"><span class="pre">range</span></code> functions.</p>
<div class="section" id="range-with-h1">
<span class="o">==</span> <span class="p">[</span><span class="mi">0</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range == [0 <=] [] [-- dup] [swons] hylomorphism'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range == [0 <=] [] [-- dup] [swons] hylomorphism'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span><span class="p">]</span>
<span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="mi">0</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">primrec</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range_reverse'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range_reverse'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span>
<span class="o">==</span> <span class="p">[</span><span class="mi">0</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[[</span><span class="o">--</span><span class="p">]</span> <span class="n">dupdip</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">5</span> <span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">]</span>
<span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="mi">0</span> <span class="o"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dupdip</span> <span class="o">--</span><span class="p">]</span> <span class="n">primrec</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger_reverse'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger_reverse'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span><span class="p">]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="n">c</span> <span class="p">[</span><span class="n">uncons</span> <span class="n">swap</span><span class="p">]</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'swuncons == uncons swap'</span><span class="p">)</span> <span class="c1"># Awkward name.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'swuncons == uncons swap'</span><span class="p">)</span> <span class="c1"># Awkward name.</span>
</pre></div>
</div>
<p>An example of a catamorphism is the sum function.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">sum</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="mi">0</span> <span class="p">[</span><span class="n">swuncons</span><span class="p">]</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == [not] 0 [swuncons] [+] hylomorphism'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == [not] 0 [swuncons] [+] hylomorphism'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
<h3>The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator<a class="headerlink" href="#the-step-combinator" title="Permalink to this headline">¶</a></h3>
<p>The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator will usually be better to use than
<code class="docutils literal notranslate"><span class="pre">catamorphism</span></code>.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[step] help'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[step] help'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Run</span> <span class="n">a</span> <span class="n">quoted</span> <span class="n">program</span> <span class="n">on</span> <span class="n">each</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">a</span> <span class="n">sequence</span><span class="o">.</span>
<span class="n">on</span> <span class="n">top</span> <span class="n">of</span> <span class="n">the</span> <span class="n">stack</span><span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == 0 swap [+] step'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == 0 swap [+] step'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
<span class="n">P</span> <span class="o">==</span> <span class="mi">1</span> <span class="o"><=</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 factorial'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 factorial'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">120</span>
<span class="n">P</span> <span class="o">==</span> <span class="ow">not</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'tails == [] swap [not] [pop] [rest dup [swons] dip] primrec'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'tails == [] swap [not] [pop] [rest dup [swons] dip] primrec'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] tails'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] tails'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[]</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span><span class="p">]]</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Recursion Combinators</a><ul>
+<li><a class="reference internal" href="#designing-recursive-functions">Designing Recursive Functions</a></li>
+<li><a class="reference internal" href="#primitive-recursive-functions">Primitive Recursive Functions</a></li>
+<li><a class="reference internal" href="#hylomorphism">Hylomorphism</a></li>
+<li><a class="reference internal" href="#hylomorphism-in-joy">Hylomorphism in Joy</a></li>
+<li><a class="reference internal" href="#derivation-of-hylomorphism-combinator">Derivation of <code class="docutils literal notranslate"><span class="pre">hylomorphism</span></code> combinator</a><ul>
+<li><a class="reference internal" href="#example-finding-triangular-numbers">Example: Finding Triangular Numbers</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#four-specializations">Four Specializations</a><ul>
+<li><a class="reference internal" href="#h1"><code class="docutils literal notranslate"><span class="pre">H1</span></code></a></li>
+<li><a class="reference internal" href="#h2"><code class="docutils literal notranslate"><span class="pre">H2</span></code></a></li>
+<li><a class="reference internal" href="#h3"><code class="docutils literal notranslate"><span class="pre">H3</span></code></a></li>
+<li><a class="reference internal" href="#h4"><code class="docutils literal notranslate"><span class="pre">H4</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#anamorphism">Anamorphism</a><ul>
+<li><a class="reference internal" href="#range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n"><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al. An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</a><ul>
+<li><a class="reference internal" href="#range-with-h1"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H1</span></code></a></li>
+<li><a class="reference internal" href="#range-with-h2"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H2</span></code></a></li>
+<li><a class="reference internal" href="#range-with-h3"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H3</span></code></a></li>
+<li><a class="reference internal" href="#range-with-h4"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H4</span></code></a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#catamorphism">Catamorphism</a><ul>
+<li><a class="reference internal" href="#the-step-combinator">The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#example-factorial-function">Example: Factorial Function</a></li>
+<li><a class="reference internal" href="#example-tails">Example: <code class="docutils literal notranslate"><span class="pre">tails</span></code></a></li>
+<li><a class="reference internal" href="#conclusion-patterns-of-recursion">Conclusion: Patterns of Recursion</a><ul>
+<li><a class="reference internal" href="#hylo-ana-cata">Hylo-, Ana-, Cata-</a></li>
+<li><a class="reference internal" href="#para">Para-, ?-, ?-</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#appendix-fun-with-symbols">Appendix: Fun with Symbols</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Recursion_Combinators.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Replacing Functions in the Dictionary — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Recursion Combinators" href="Recursion_Combinators.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="replacing-functions-in-the-dictionary">
<p>For now, there is no way to define new functions from within the Joy
language. All functions (and the interpreter) all accept and return a
dictionary parameter (in addition to the stack and expression) so that
-we can implement e.g. a function that adds new functions to the
+we can implement e.g. a function that adds new functions to the
dictionary. However, there’s no function that does that. Adding a new
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
</pre></div>
</div>
<div class="section" id="a-long-trace">
<h2>A long trace<a class="headerlink" href="#a-long-trace" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">23</span> <span class="mi">18</span><span class="p">]</span> <span class="n">average</span>
<p>An efficient <code class="docutils literal notranslate"><span class="pre">sum</span></code> function is already in the library. But for
<code class="docutils literal notranslate"><span class="pre">size</span></code> we can use a “compiled” version hand-written in Python to speed
up evaluation and make the trace more readable.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">SimpleFunctionWrapper</span>
-<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="kn">import</span> <span class="n">iter_stack</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.library</span> <span class="k">import</span> <span class="n">SimpleFunctionWrapper</span>
+<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="k">import</span> <span class="n">iter_stack</span>
<span class="nd">@SimpleFunctionWrapper</span>
</div>
<p>Now we replace the old version in the dictionary with the new version,
and re-evaluate the expression.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'size'</span><span class="p">]</span> <span class="o">=</span> <span class="n">size</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'size'</span><span class="p">]</span> <span class="o">=</span> <span class="n">size</span>
</pre></div>
</div>
</div>
<div class="section" id="a-shorter-trace">
<h2>A shorter trace<a class="headerlink" href="#a-shorter-trace" title="Permalink to this headline">¶</a></h2>
<p>You can see that <code class="docutils literal notranslate"><span class="pre">size</span></code> now executes in a single step.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">23</span> <span class="mi">18</span><span class="p">]</span> <span class="n">average</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Replacing Functions in the Dictionary</a><ul>
+<li><a class="reference internal" href="#a-long-trace">A long trace</a></li>
+<li><a class="reference internal" href="#replacing-size-with-a-python-version">Replacing <code class="docutils literal notranslate"><span class="pre">size</span></code> with a Python version</a></li>
+<li><a class="reference internal" href="#a-shorter-trace">A shorter trace</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Replacing.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The Four Fundamental Operations of Definite Action — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="∂RE" href="Derivatives_of_Regular_Expressions.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="the-four-fundamental-operations-of-definite-action">
<p>All definite actions (computer program) can be defined by four
fundamental patterns of combination:</p>
<ol class="arabic simple">
-<li><p>Sequence</p></li>
-<li><p>Branch</p></li>
-<li><p>Loop</p></li>
-<li><p>Parallel</p></li>
+<li>Sequence</li>
+<li>Branch</li>
+<li>Loop</li>
+<li>Parallel</li>
</ol>
<div class="section" id="sequence">
<h2>Sequence<a class="headerlink" href="#sequence" title="Permalink to this headline">¶</a></h2>
(“join” or “wait”) of the results of the functions after they finish.</p>
<p>The current implementaions and the following definitions <em>are not
actually parallel</em> (yet), but there is no reason they couldn’t be
-reimplemented in terms of e.g. Python threads. I am not concerned with
+reimplemented in terms of e.g. Python threads. I am not concerned with
performance of the system just yet, only the elegance of the code it
allows us to write.</p>
<div class="section" id="cleave">
</pre></div>
</div>
<p>There is no reason why the implementation of <code class="docutils literal notranslate"><span class="pre">map</span></code> couldn’t distribute
-the <code class="docutils literal notranslate"><span class="pre">Q</span></code> function over e.g. a pool of worker CPUs.</p>
+the <code class="docutils literal notranslate"><span class="pre">Q</span></code> function over e.g. a pool of worker CPUs.</p>
</div>
<div class="section" id="pam">
<h3><code class="docutils literal notranslate"><span class="pre">pam</span></code><a class="headerlink" href="#pam" title="Permalink to this headline">¶</a></h3>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">The Four Fundamental Operations of Definite Action</a><ul>
+<li><a class="reference internal" href="#sequence">Sequence</a></li>
+<li><a class="reference internal" href="#branch">Branch</a><ul>
+<li><a class="reference internal" href="#ifte"><code class="docutils literal notranslate"><span class="pre">ifte</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#loop">Loop</a><ul>
+<li><a class="reference internal" href="#while"><code class="docutils literal notranslate"><span class="pre">while</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#parallel">Parallel</a><ul>
+<li><a class="reference internal" href="#cleave"><code class="docutils literal notranslate"><span class="pre">cleave</span></code></a></li>
+<li><a class="reference internal" href="#apply-functions">“Apply” Functions</a></li>
+<li><a class="reference internal" href="#map"><code class="docutils literal notranslate"><span class="pre">map</span></code></a></li>
+<li><a class="reference internal" href="#pam"><code class="docutils literal notranslate"><span class="pre">pam</span></code></a></li>
+<li><a class="reference internal" href="#handling-other-kinds-of-join">Handling Other Kinds of Join</a><ul>
+<li><a class="reference internal" href="#first-to-finish">first-to-finish</a></li>
+<li><a class="reference internal" href="#fulminators">“Fulminators”</a></li>
+</ul>
+</li>
+</ul>
+</li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/The_Four_Operations.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Treating Trees II: treestep — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Using x to Generate Values" href="Generator_Programs.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="treating-trees-ii-treestep">
</div>
<div class="section" id="define-treestep">
<h2>Define <code class="docutils literal notranslate"><span class="pre">treestep</span></code><a class="headerlink" href="#define-treestep" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span><span class="p">,</span> <span class="n">DefinitionWrapper</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span><span class="p">,</span> <span class="n">DefinitionWrapper</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1"> _treestep_0 == [[not] swap] dip</span>
<span class="s1"> _treestep_1 == [dip] cons [uncons] swoncat</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sumtree</span> <span class="o">==</span> <span class="p">[</span><span class="n">pop</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="nb">sum</span> <span class="o">+</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sumtree == [pop 0] [] [sum +] treestep'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sumtree == [pop 0] [] [sum +] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<p>Running this function on an empty tree value gives zero:</p>
<span class="mi">0</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] sumtree'</span><span class="p">)</span> <span class="c1"># Empty tree.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] sumtree'</span><span class="p">)</span> <span class="c1"># Empty tree.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span>
<span class="n">n</span><span class="o">+</span><span class="n">m</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23] sumtree'</span><span class="p">)</span> <span class="c1"># No child trees.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23] sumtree'</span><span class="p">)</span> <span class="c1"># No child trees.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 []] sumtree'</span><span class="p">)</span> <span class="c1"># Child tree, empty.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 []] sumtree'</span><span class="p">)</span> <span class="c1"># Child tree, empty.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [4]] [3]] sumtree'</span><span class="p">)</span> <span class="c1"># Non-empty child trees.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [4]] [3]] sumtree'</span><span class="p">)</span> <span class="c1"># Non-empty child trees.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">32</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] sumtree'</span><span class="p">)</span> <span class="c1"># Etc...</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] sumtree'</span><span class="p">)</span> <span class="c1"># Etc...</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">49</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep'</span><span class="p">)</span> <span class="c1"># Alternate "spelling".</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep'</span><span class="p">)</span> <span class="c1"># Alternate "spelling".</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">49</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep'</span><span class="p">)</span> <span class="c1"># Replace each node.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep'</span><span class="p">)</span> <span class="c1"># Replace each node.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">23</span> <span class="p">[</span><span class="mi">23</span> <span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="p">[</span><span class="mi">23</span><span class="p">]]</span> <span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="p">[</span><span class="mi">23</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">1</span><span class="p">]]</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[]]]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span>
</pre></div>
</div>
<p>This doesn’t quite work:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="s1">'B'</span> <span class="s1">'B'</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="p">[</span><span class="n">flatten</span> <span class="n">cons</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">9</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">8</span> <span class="mi">6</span> <span class="mi">7</span><span class="p">]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span> <span class="p">[</span><span class="n">i</span> <span class="n">roll</span><span class="o"><</span> <span class="n">swons</span> <span class="n">concat</span><span class="p">]</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll< swons concat] treestep'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll< swons concat] treestep'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span><span class="p">]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">key</span> <span class="n">value</span><span class="p">]</span> <span class="n">N</span> <span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="n">C</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'key'</span> <span class="s1">'value'</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[[</span><span class="s1">'left'</span><span class="p">]</span> <span class="p">[</span><span class="s1">'right'</span><span class="p">]]</span> <span class="p">[[</span><span class="ow">not</span><span class="p">]</span> <span class="p">[</span><span class="s1">'B'</span><span class="p">]</span> <span class="p">[</span><span class="n">uncons</span> <span class="p">[</span><span class="s1">'N'</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="p">[</span><span class="s1">'C'</span><span class="p">]</span> <span class="n">genrec</span><span class="p">]</span> <span class="s1">'C'</span>
<div class="section" id="treegrind-with-step">
<h2><code class="docutils literal notranslate"><span class="pre">treegrind</span></code> with <code class="docutils literal notranslate"><span class="pre">step</span></code><a class="headerlink" href="#treegrind-with-step" title="Permalink to this headline">¶</a></h2>
<p>Iteration through the nodes</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] ["N"] [step] treegrind'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] ["N"] [step] treegrind'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span>
</pre></div>
</div>
<p>Sum the nodes’ keys.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">44</span>
</pre></div>
</div>
<p>Rebuild the tree using <code class="docutils literal notranslate"><span class="pre">map</span></code> (imitating <code class="docutils literal notranslate"><span class="pre">treestep</span></code>.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="mi">103</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">102</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[[</span><span class="mi">109</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">105</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">104</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[[</span><span class="mi">108</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">106</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">107</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
</pre></div>
</div>
<p>To me, that seems simpler than the <code class="docutils literal notranslate"><span class="pre">genrec</span></code> version.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
<span class="s1"> T> == pop [first] dip i</span>
<span class="s1"> T< == pop [second] dip i</span>
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
<span class="s1">[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
<span class="s1">[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a><ul>
+<li><a class="reference internal" href="#derive-the-recursive-function">Derive the recursive function.</a></li>
+<li><a class="reference internal" href="#extract-the-givens-to-parameterize-the-program">Extract the givens to parameterize the program.</a><ul>
+<li><a class="reference internal" href="#alternate-extract-the-givens-to-parameterize-the-program">(alternate) Extract the givens to parameterize the program.</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#define-treestep">Define <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
+<li><a class="reference internal" href="#examples">Examples</a></li>
+<li><a class="reference internal" href="#redefining-the-ordered-binary-tree-in-terms-of-treestep">Redefining the Ordered Binary Tree in terms of <code class="docutils literal notranslate"><span class="pre">treestep</span></code>.</a><ul>
+<li><a class="reference internal" href="#traversal">Traversal</a></li>
+<li><a class="reference internal" href="#in-order-traversal">In-order traversal</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#with-treegrind">With <code class="docutils literal notranslate"><span class="pre">treegrind</span></code>?</a></li>
+<li><a class="reference internal" href="#treegrind-with-step"><code class="docutils literal notranslate"><span class="pre">treegrind</span></code> with <code class="docutils literal notranslate"><span class="pre">step</span></code></a></li>
+<li><a class="reference internal" href="#do-we-have-the-flexibility-to-reimplement-tree-get">Do we have the flexibility to reimplement <code class="docutils literal notranslate"><span class="pre">Tree-get</span></code>?</a><ul>
+<li><a class="reference internal" href="#the-predicate-p">The predicate <code class="docutils literal notranslate"><span class="pre">P</span></code></a></li>
+<li><a class="reference internal" href="#e"><code class="docutils literal notranslate"><span class="pre">E</span></code></a></li>
+<li><a class="reference internal" href="#t-and-t"><code class="docutils literal notranslate"><span class="pre">T<</span></code> and <code class="docutils literal notranslate"><span class="pre">T></span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#putting-it-together">Putting it together</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Treestep.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Type Checking — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="No Updates" href="NoUpdates.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="type-checking">
<h1>Type Checking<a class="headerlink" href="#type-checking" title="Permalink to this headline">¶</a></h1>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">sys</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">sys</span>
<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span>
<span class="nb">format</span><span class="o">=</span><span class="s1">'</span><span class="si">%(message)s</span><span class="s1">'</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.utils.types</span> <span class="kn">import</span> <span class="p">(</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.utils.types</span> <span class="k">import</span> <span class="p">(</span>
<span class="n">doc_from_stack_effect</span><span class="p">,</span>
<span class="n">infer</span><span class="p">,</span>
<span class="n">reify</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">D</span> <span class="o">=</span> <span class="n">FUNCTIONS</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">D</span> <span class="o">=</span> <span class="n">FUNCTIONS</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
<span class="k">del</span> <span class="n">D</span><span class="p">[</span><span class="s1">'product'</span><span class="p">]</span>
<span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">D</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="an-example">
<h2>An Example<a class="headerlink" href="#an-example" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rrest</span><span class="p">,</span> <span class="n">ccons</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rrest</span><span class="p">,</span> <span class="n">ccons</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>25 (--) ∘ pop swap rolldown rrest ccons
40 ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) ∘
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a4</span> <span class="n">a5</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="n">a3</span> <span class="n">a2</span> <span class="n">a1</span> <span class="o">--</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a3</span> <span class="o">...</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.parser</span> <span class="kn">import</span> <span class="n">text_to_expression</span>
-<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="kn">import</span> <span class="n">stack_to_string</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">joy.parser</span> <span class="k">import</span> <span class="n">text_to_expression</span>
+<span class="kn">from</span> <span class="nn">joy.utils.stack</span> <span class="k">import</span> <span class="n">stack_to_string</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'0 1 2 [3 4]'</span><span class="p">)</span> <span class="c1"># reverse order</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'0 1 2 [3 4]'</span><span class="p">)</span> <span class="c1"># reverse order</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">4</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">u</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">a2</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a4</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">a5</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="unification-works-in-reverse">
<h2>Unification Works “in Reverse”<a class="headerlink" href="#unification-works-in-reverse" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[2 3]'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[2 3]'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fo</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># output side, not input side</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fo</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># output side, not input side</span>
<span class="n">u</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a2</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="failing-a-check">
<h2>Failing a Check<a class="headerlink" href="#failing-a-check" title="Permalink to this headline">¶</a></h2>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>25 (--) ∘ dup mul
31 (i1 -- i2) ∘
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'"two"'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'"two"'</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'two'</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)</span>
<span class="k">except</span> <span class="n">JoyTypeError</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">err</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Type Checking</a><ul>
+<li><a class="reference internal" href="#an-example">An Example</a></li>
+<li><a class="reference internal" href="#unification-works-in-reverse">Unification Works “in Reverse”</a></li>
+<li><a class="reference internal" href="#failing-a-check">Failing a Check</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/TypeChecking.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The Blissful Elegance of Typing Joy — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Type Checking" href="TypeChecking.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="the-blissful-elegance-of-typing-joy">
what I like to call Yin functions. (Yin functions are those that only
rearrange values in stacks, as opposed to Yang functions that actually
work on the values themselves.)</p>
-<div class="section" id="part-i-poial-s-rules">
-<h2>Part I: Pöial’s Rules<a class="headerlink" href="#part-i-poial-s-rules" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="part-i-poials-rules">
+<h2>Part I: Pöial’s Rules<a class="headerlink" href="#part-i-poials-rules" title="Permalink to this headline">¶</a></h2>
<p><a class="reference external" href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.212.6026">“Typing Tools for Typeless Stack Languages” by Jaanus
Pöial</a></p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nd">@INPROCEEDINGS</span><span class="p">{</span><span class="n">Pöial06typingtools</span><span class="p">,</span>
<p>The third rule is actually two rules. These two rules deal with
composing functions when the second one will consume one of items the
first one produces. The two types must be
-<a class="reference external" href="https://en.wikipedia.org/wiki/Robinson's_unification_algorithm">*unified*</a>
+<a class="reference external" href="https://en.wikipedia.org/wiki/Robinson's_unification_algorithm">unified</a>
or a type conflict declared.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
-------------------------------
<div class="section" id="compiling-popswaproll">
<h3>Compiling <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<</span></code><a class="headerlink" href="#compiling-popswaproll" title="Permalink to this headline">¶</a></h3>
<p>The simplest way to “compile” this function would be something like:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
<span class="k">return</span> <span class="n">rolldown</span><span class="p">(</span><span class="o">*</span><span class="n">swap</span><span class="p">(</span><span class="o">*</span><span class="n">pop</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">d</span><span class="p">)))</span>
</pre></div>
</div>
</pre></div>
</div>
<p>We should be able to directly write out a Python function like:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">poswrd</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
</pre></div>
</div>
<p>From this stack effect comment it should be possible to construct the
following Python code:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
</pre></div>
<h3>Representing Stack Effect Comments in Python<a class="headerlink" href="#representing-stack-effect-comments-in-python" title="Permalink to this headline">¶</a></h3>
<p>I’m going to use pairs of tuples of type descriptors, which will be
integers or tuples of type descriptors:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">roll_dn</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">roll_dn</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">pop</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,),</span> <span class="p">()</span>
</div>
<div class="section" id="compose">
<h3><code class="docutils literal notranslate"><span class="pre">compose()</span></code><a class="headerlink" href="#compose" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
</div>
<div class="section" id="unify">
<h3><code class="docutils literal notranslate"><span class="pre">unify()</span></code><a class="headerlink" href="#unify" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
</div>
<div class="section" id="update">
<h3><code class="docutils literal notranslate"><span class="pre">update()</span></code><a class="headerlink" href="#update" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">term</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">term</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
<span class="k">return</span> <span class="n">s</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">term</span><span class="p">,</span> <span class="n">term</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">inner</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">term</span><span class="p">)</span>
</div>
<div class="section" id="relabel">
<h3><code class="docutils literal notranslate"><span class="pre">relabel()</span></code><a class="headerlink" href="#relabel" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">relabel</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">relabel</span><span class="p">(</span><span class="n">left</span><span class="p">,</span> <span class="n">right</span><span class="p">):</span>
<span class="k">return</span> <span class="n">left</span><span class="p">,</span> <span class="n">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_1000</span><span class="p">(</span><span class="n">right</span><span class="p">):</span>
</div>
<div class="section" id="delabel">
<h3><code class="docutils literal notranslate"><span class="pre">delabel()</span></code><a class="headerlink" href="#delabel" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{</span><span class="n">u</span><span class="p">:</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">u</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">_unique</span><span class="p">(</span><span class="n">f</span><span class="p">)))}</span>
<span class="k">return</span> <span class="n">update</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
<p>At last we put it all together in a function <code class="docutils literal notranslate"><span class="pre">C()</span></code> that accepts two
stack effect comments and returns their composition (or raises and
exception if they can’t be composed due to type conflicts.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
<span class="n">fg</span> <span class="o">=</span> <span class="n">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">)</span>
<span class="k">return</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it out.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">),</span> <span class="n">roll_dn</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">),</span> <span class="n">roll_dn</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">poswrd</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">poswrd</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">))</span>
<span class="n">poswrd</span>
</pre></div>
</div>
<p>Here’s that trick to represent functions like <code class="docutils literal notranslate"><span class="pre">rest</span></code> and <code class="docutils literal notranslate"><span class="pre">cons</span></code> that
manipulate stacks. We use a cons-list of tuples and give the tails their
own numbers. Then everything above already works.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rest</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,)</span>
<span class="n">cons</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">poswrd</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">poswrd</span><span class="p">,</span> <span class="n">rest</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">))</span>
<span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">roll_dn</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
<span class="n">F</span>
</pre></div>
<h3>Dealing with <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code><a class="headerlink" href="#dealing-with-cons-and-uncons" title="Permalink to this headline">¶</a></h3>
<p>However, if we try to compose e.g. <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code> it won’t
work:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">uncons</span> <span class="o">=</span> <span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">e</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">e</span>
<p>The problem is that the <code class="docutils literal notranslate"><span class="pre">unify()</span></code> function as written doesn’t handle
the case when both terms are tuples. We just have to add a clause to
deal with this recursively:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
<span class="k">return</span> <span class="n">s</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<div class="section" id="part-iii-compiling-yin-functions">
<h2>Part III: Compiling Yin Functions<a class="headerlink" href="#part-iii-compiling-yin-functions" title="Permalink to this headline">¶</a></h2>
<p>Now consider the Python function we would like to derive:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span>
</pre></div>
</div>
<p>And compare it to the input stack effect comment tuple we just computed:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">3</span><span class="p">,</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
</div>
<p>Eh?</p>
<p>And the return tuple</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">)),)</span>
<h3>Python Identifiers<a class="headerlink" href="#python-identifiers" title="Permalink to this headline">¶</a></h3>
<p>We want to substitute Python identifiers for the integers. I’m going to
repurpose <code class="docutils literal notranslate"><span class="pre">joy.parser.Symbol</span></code> class for this:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
-<span class="kn">from</span> <span class="nn">joy.parser</span> <span class="kn">import</span> <span class="n">Symbol</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">defaultdict</span>
+<span class="kn">from</span> <span class="nn">joy.parser</span> <span class="k">import</span> <span class="n">Symbol</span>
<span class="k">def</span> <span class="nf">_names_for</span><span class="p">():</span>
effect comment tuples to reasonable text format. There are some details
in how this code works that related to stuff later in the notebook, so
you should skip it for now and read it later if you’re interested.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">'(</span><span class="si">%s</span><span class="s1">--</span><span class="si">%s</span><span class="s1">)'</span> <span class="o">%</span> <span class="p">(</span>
<span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">_to_str</span><span class="p">,</span> <span class="n">inputs</span> <span class="o">+</span> <span class="p">(</span><span class="s1">''</span><span class="p">,))),</span>
<span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">_to_str</span><span class="p">,</span> <span class="p">(</span><span class="s1">''</span><span class="p">,)</span> <span class="o">+</span> <span class="n">outputs</span><span class="p">))</span>
<p>Now we can write a compiler function to emit Python source code. (The
underscore suffix distiguishes it from the built-in <code class="docutils literal notranslate"><span class="pre">compile()</span></code>
function.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
<span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">identifiers</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<p>Here it is in action:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">source</span> <span class="o">=</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">source</span> <span class="o">=</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">source</span>
</pre></div>
</pre></div>
</div>
<p>Compare:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F_python</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="p">((</span><span class="n">a</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">))))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="p">((</span><span class="n">d</span><span class="p">,</span> <span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">S0</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
</pre></div>
</div>
<p>Next steps:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="p">{}</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">L</span> <span class="o">=</span> <span class="p">{}</span>
<span class="nb">eval</span><span class="p">(</span><span class="nb">compile</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="s1">'__main__'</span><span class="p">,</span> <span class="s1">'single'</span><span class="p">),</span> <span class="p">{},</span> <span class="n">L</span><span class="p">)</span>
</pre></div>
</div>
<p>Let’s try it out:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
-<span class="kn">from</span> <span class="nn">joy.library</span> <span class="kn">import</span> <span class="n">SimpleFunctionWrapper</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
+<span class="kn">from</span> <span class="nn">joy.library</span> <span class="k">import</span> <span class="n">SimpleFunctionWrapper</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'F'</span><span class="p">]</span> <span class="o">=</span> <span class="n">SimpleFunctionWrapper</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="s1">'F'</span><span class="p">])</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'F'</span><span class="p">]</span> <span class="o">=</span> <span class="n">SimpleFunctionWrapper</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="s1">'F'</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 5 ...] 2 3 1 F'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 5 ...] 2 3 1 F'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="o">...</span><span class="p">]</span>
<h3>Compiling Library Functions<a class="headerlink" href="#compiling-library-functions" title="Permalink to this headline">¶</a></h3>
<p>We can use <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> to generate many primitives in the library
from their stack effect comments:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
<span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
<span class="nb">print</span>
<span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span><span class="p">)</span>
<span class="nb">print</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span> <span class="p">(</span><span class="mi">1</span> <span class="o">--</span> <span class="mi">1</span> <span class="mi">1</span><span class="p">)</span>
</pre></div>
</div>
-<p>And <code class="docutils literal notranslate"><span class="pre">mul</span></code> accepts two “numbers” (we’re ignoring ints vs. floats vs.
-complex, etc., for now) and returns just one:</p>
+<p>And <code class="docutils literal notranslate"><span class="pre">mul</span></code> accepts two “numbers” (we’re ignoring ints vs. floats
+vs. complex, etc., for now) and returns just one:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span> <span class="p">(</span><span class="n">n</span> <span class="n">n</span> <span class="o">--</span> <span class="n">n</span><span class="p">)</span>
</pre></div>
</div>
Python class hierarchy of Joy types and use the <code class="docutils literal notranslate"><span class="pre">issubclass()</span></code> method
to establish domain ordering, as well as other handy behaviour that will
make it fairly easy to reuse most of the code above.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">AnyJoyType</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">AnyJoyType</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="n">prefix</span> <span class="o">=</span> <span class="s1">'a'</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
- <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span><span class="p">)</span>
- <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
<span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">prefix</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">prefix</span>
<span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">number</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span>
<span class="p">)</span>
- <span class="k">def</span> <span class="fm">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
- <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="n">other</span><span class="p">)</span>
<span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
- <span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
</pre></div>
</div>
<p>Mess with it a little:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">permutations</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">permutations</span>
</pre></div>
</div>
<p>“Any” types can be specialized to numbers and stacks, but not vice
versa:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="mi">2</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="mi">2</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">'>='</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">a</span> <span class="o">>=</span> <span class="n">b</span>
</pre></div>
</div>
<p>Our crude <a class="reference external" href="https://en.wikipedia.org/wiki/Numerical_tower">Numerical
Tower</a> of <em>numbers</em> >
<em>floats</em> > <em>integers</em> works as well (but we’re not going to use it yet):</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">FloatJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">IntJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">)),</span> <span class="mi">2</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">permutations</span><span class="p">((</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">FloatJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">),</span> <span class="n">IntJoyType</span><span class="p">(</span><span class="mi">0</span><span class="p">)),</span> <span class="mi">2</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">a</span><span class="p">,</span> <span class="s1">'>='</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">a</span> <span class="o">>=</span> <span class="n">b</span>
</pre></div>
</div>
</div>
<div class="section" id="typing-sqr">
<h3>Typing <code class="docutils literal notranslate"><span class="pre">sqr</span></code><a class="headerlink" href="#typing-sqr" title="Permalink to this headline">¶</a></h3>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">mul</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">dup</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a1</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">mul</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">),</span> <span class="p">(</span><span class="n">n3</span><span class="p">,))</span>
<div class="section" id="modifying-the-inferencer">
<h3>Modifying the Inferencer<a class="headerlink" href="#modifying-the-inferencer" title="Permalink to this headline">¶</a></h3>
<p>Re-labeling still works fine:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">foo</span> <span class="o">=</span> <span class="n">relabel</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
<span class="n">foo</span>
</pre></div>
<h4><code class="docutils literal notranslate"><span class="pre">delabel()</span></code> version 2<a class="headerlink" href="#delabel-version-2" title="Permalink to this headline">¶</a></h4>
<p>The <code class="docutils literal notranslate"><span class="pre">delabel()</span></code> function needs an overhaul. It now has to keep track
of how many labels of each domain it has “seen”.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">Counter</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">Counter</span>
<span class="k">def</span> <span class="nf">delabel</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">seen</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">delabel</span><span class="p">(</span><span class="n">inner</span><span class="p">,</span> <span class="n">seen</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">inner</span> <span class="ow">in</span> <span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">delabel</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">delabel</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a1</span><span class="p">,),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">a1</span><span class="p">)),</span> <span class="p">((</span><span class="n">n1</span><span class="p">,</span> <span class="n">n2</span><span class="p">),</span> <span class="p">(</span><span class="n">n3</span><span class="p">,)))</span>
</div>
<div class="section" id="unify-version-3">
<h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 3<a class="headerlink" href="#unify-version-3" title="Permalink to this headline">¶</a></h4>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
</pre></div>
</div>
<p>Rewrite the stack effect comments:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">defs</span><span class="p">():</span>
<span class="n">rolldown</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">]),</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">return</span> <span class="nb">locals</span><span class="p">()</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">DEFS</span> <span class="o">=</span> <span class="n">defs</span><span class="p">()</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DEFS</span> <span class="o">=</span> <span class="n">defs</span><span class="p">()</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
<span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
</pre></div>
</div>
<span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">DEFS</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">DEFS</span><span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="compose-dup-and-mul">
<h4>Compose <code class="docutils literal notranslate"><span class="pre">dup</span></code> and <code class="docutils literal notranslate"><span class="pre">mul</span></code><a class="headerlink" href="#compose-dup-and-mul" title="Permalink to this headline">¶</a></h4>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">n1</span><span class="p">,),</span> <span class="p">(</span><span class="n">n2</span><span class="p">,))</span>
</pre></div>
</div>
<p>Revisit the <code class="docutils literal notranslate"><span class="pre">F</span></code> function, works fine.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">F</span> <span class="o">=</span> <span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">))</span>
<span class="n">F</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">a3</span><span class="p">,</span> <span class="n">a4</span><span class="p">,</span> <span class="n">a5</span><span class="p">),</span> <span class="p">((</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">F</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">a1</span> <span class="n">a2</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">a3</span> <span class="n">a4</span> <span class="n">a5</span> <span class="o">--</span> <span class="p">[</span><span class="n">a4</span> <span class="n">a3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
</div>
<p>Some otherwise inefficient functions are no longer to be feared. We can
also get the effect of combinators in some limited cases.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">neato</span><span class="p">(</span><span class="o">*</span><span class="n">funcs</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">neato</span><span class="p">(</span><span class="o">*</span><span class="n">funcs</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="n">funcs</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [swap] dip</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [swap] dip</span>
<span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="o">--</span> <span class="n">a2</span> <span class="n">a1</span> <span class="n">a3</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [popop] dipd</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># e.g. [popop] dipd</span>
<span class="n">neato</span><span class="p">(</span><span class="n">popdd</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">pop</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="n">a2</span> <span class="n">a3</span> <span class="n">a4</span> <span class="o">--</span> <span class="n">a3</span> <span class="n">a4</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Reverse the order of the top three items.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># Reverse the order of the top three items.</span>
<span class="n">neato</span><span class="p">(</span><span class="n">rollup</span><span class="p">,</span> <span class="n">swap</span><span class="p">)</span>
</pre></div>
</div>
<h4><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 2<a class="headerlink" href="#compile-version-2" title="Permalink to this headline">¶</a></h4>
<p>Because the type labels represent themselves as valid Python identifiers
the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function doesn’t need to generate them anymore:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span> <span class="o">=</span> <span class="n">f</span>
<span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">)</span>
<span class="s1"> return </span><span class="si">%s</span><span class="s1">'''</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'F'</span><span class="p">,</span> <span class="n">F</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">F</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="k">return</span> <span class="p">((</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">stack</span><span class="p">)</span>
</pre></div>
</div>
-<p>But it cannot magically create new functions that involve e.g. math and
+<p>But it cannot magically create new functions that involve e.g. math and
such. Note that this is <em>not</em> a <code class="docutils literal notranslate"><span class="pre">sqr</span></code> function implementation:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'sqr'</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'sqr'</span><span class="p">,</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">mul</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sqr</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<p>The functions that <em>can</em> be compiled are the ones that have only
<code class="docutils literal notranslate"><span class="pre">AnyJoyType</span></code> and <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> labels in their stack effect
comments. We can write a function to check that:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">imap</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">imap</span>
<span class="k">def</span> <span class="nf">compilable</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">)</span> <span class="ow">and</span> <span class="nb">all</span><span class="p">(</span><span class="n">imap</span><span class="p">(</span><span class="n">compilable</span><span class="p">,</span> <span class="n">f</span><span class="p">))</span> <span class="ow">or</span> <span class="n">stacky</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">defs</span><span class="p">()</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
<span class="k">if</span> <span class="n">compilable</span><span class="p">(</span><span class="n">stack_effect_comment</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
</pre></div>
the “truthiness” of <code class="docutils literal notranslate"><span class="pre">StackJoyType</span></code> to false to let e.g.
<code class="docutils literal notranslate"><span class="pre">joy.utils.stack.concat</span></code> work with our stack effect comment cons-list
tuples.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
<span class="k">if</span> <span class="n">s</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span> <span class="c1"># s can also be the empty dict, which is ok.</span>
</div>
<p>I don’t want to rewrite all the defs myself, so I’ll write a little
conversion function instead. This is programmer’s laziness.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sequence_to_stack</span><span class="p">(</span><span class="n">seq</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="n">StackJoyType</span><span class="p">(</span><span class="mi">23</span><span class="p">)):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">sequence_to_stack</span><span class="p">(</span><span class="n">seq</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="n">StackJoyType</span><span class="p">(</span><span class="mi">23</span><span class="p">)):</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">seq</span><span class="p">:</span> <span class="n">stack</span> <span class="o">=</span> <span class="n">item</span><span class="p">,</span> <span class="n">stack</span>
<span class="k">return</span> <span class="n">stack</span>
<span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="p">(</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s1</span><span class="p">))))))</span>
<div class="section" id="doc-from-stack-effect-version-2">
<h3><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code> version 2<a class="headerlink" href="#doc-from-stack-effect-version-2" title="Permalink to this headline">¶</a></h3>
<p>Clunky junk, but it will suffice for now.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">doc_from_stack_effect</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">outputs</span><span class="p">):</span>
<span class="n">switch</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="c1"># Do we need to display the '...' for the rest of the main stack?</span>
<span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">_f</span><span class="p">(</span><span class="n">inputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">),</span> <span class="n">_f</span><span class="p">(</span><span class="n">outputs</span><span class="p">,</span> <span class="n">switch</span><span class="p">)</span>
<span class="k">if</span> <span class="n">switch</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
<span class="k">return</span> <span class="s1">'[</span><span class="si">%s</span><span class="s1">]'</span> <span class="o">%</span> <span class="s1">' '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">name</span><span class="p">,</span> <span class="n">stack_effect_comment</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">NEW_DEFS</span><span class="o">.</span><span class="n">items</span><span class="p">()):</span>
<span class="nb">print</span> <span class="n">name</span><span class="p">,</span> <span class="s1">'='</span><span class="p">,</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack_effect_comment</span><span class="p">)</span>
</pre></div>
</div>
<span class="n">uncons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">stack</span><span class="p">)</span>
<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">))</span>
<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">uncons</span><span class="p">)))</span>
<span class="nb">print</span> <span class="p">;</span> <span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">reduce</span><span class="p">(</span><span class="n">C</span><span class="p">,</span> <span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">uncons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)))</span>
<span class="p">(</span><span class="o">...</span> <span class="n">a1</span> <span class="o">--</span> <span class="o">...</span> <span class="n">a1</span> <span class="p">[</span><span class="n">a1</span> <span class="o">...</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">...</span> <span class="n">a2</span> <span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="o">...</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="p">[[</span><span class="n">a2</span> <span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">...</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">Q</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Q</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">ccons</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
<span class="n">Q</span>
</pre></div>
<h4><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 3<a class="headerlink" href="#compile-version-3" title="Permalink to this headline">¶</a></h4>
<p>This makes the <code class="docutils literal notranslate"><span class="pre">compile_()</span></code> function pretty simple as the stack effect
comments are now already in the form needed for the Python code:</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compile_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">i</span><span class="p">,</span> <span class="n">o</span> <span class="o">=</span> <span class="n">f</span>
<span class="k">if</span> <span class="n">doc</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">doc</span> <span class="o">=</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
<span class="s1"> return </span><span class="si">%s</span><span class="s1">'''</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">doc</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">o</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'Q'</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">compile_</span><span class="p">(</span><span class="s1">'Q'</span><span class="p">,</span> <span class="n">Q</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">Q</span><span class="p">(</span><span class="n">stack</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">),</span> <span class="p">((</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">s2</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">unstack</span> <span class="o">=</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">unstack</span> <span class="o">=</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="n">enstacken</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">unstack</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">unstack</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">enstacken</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">enstacken</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="o">.</span><span class="mf">0.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">a1</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">enstacken</span><span class="p">))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">enstacken</span><span class="p">))</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">.</span><span class="mf">2.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="n">unstack</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="n">s1</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)),</span> <span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span>
<div class="section" id="part-vi-multiple-stack-effects">
<h2>Part VI: Multiple Stack Effects<a class="headerlink" href="#part-vi-multiple-stack-effects" title="Permalink to this headline">¶</a></h2>
<p>…</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'i'</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">IntJoyType</span><span class="p">(</span><span class="n">NumberJoyType</span><span class="p">):</span> <span class="n">prefix</span> <span class="o">=</span> <span class="s1">'i'</span>
<span class="n">F</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">FloatJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
<span class="n">I</span> <span class="o">=</span> <span class="nb">map</span><span class="p">(</span><span class="n">IntJoyType</span><span class="p">,</span> <span class="n">_R</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">muls</span> <span class="o">=</span> <span class="p">[</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">muls</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
<span class="p">((</span><span class="n">F</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">I</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
<span class="p">((</span><span class="n">I</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="p">(</span><span class="n">F</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span>
<span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">(</span><span class="n">f1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">muls</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">e</span> <span class="o">=</span> <span class="n">C</span><span class="p">(</span><span class="n">dup</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="p">(</span><span class="n">a1</span> <span class="o">--</span> <span class="n">a1</span> <span class="n">a1</span><span class="p">)</span> <span class="p">(</span><span class="n">f1</span> <span class="n">f2</span> <span class="o">--</span> <span class="n">f3</span><span class="p">)</span> <span class="p">(</span><span class="n">f1</span> <span class="o">--</span> <span class="n">f2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">product</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">product</span>
<span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">)))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">mul</span><span class="p">]):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">n1</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">{</span><span class="n">c</span><span class="p">:</span> <span class="n">a</span><span class="p">,</span> <span class="n">d</span><span class="p">:</span> <span class="n">e</span><span class="p">,</span> <span class="o">.</span><span class="mf">1.</span><span class="p">:</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">.</span><span class="mf">0.</span><span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">KleeneStar</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">KleeneStar</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
<span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
<span class="bp">self</span><span class="o">.</span><span class="n">prefix</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
- <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s1">'</span><span class="si">%s%i</span><span class="s1">*'</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">kind</span><span class="o">.</span><span class="n">prefix</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">another</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span><span class="p">(</span><span class="mi">10000</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">count</span><span class="p">)</span>
- <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span>
<span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
<span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">number</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">number</span>
<span class="p">)</span>
- <span class="k">def</span> <span class="fm">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__ge__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">kind</span> <span class="o">>=</span> <span class="n">other</span><span class="o">.</span><span class="n">kind</span>
- <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">+</span> <span class="n">other</span><span class="p">)</span>
<span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
- <span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
<span class="k">class</span> <span class="nc">AnyStarJoyType</span><span class="p">(</span><span class="n">KleeneStar</span><span class="p">):</span> <span class="n">kind</span> <span class="o">=</span> <span class="n">AnyJoyType</span>
<div class="section" id="unify-version-4">
<h4><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 4<a class="headerlink" href="#unify-version-4" title="Permalink to this headline">¶</a></h4>
<p>Can now return multiple results…</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">unify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">s</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">s</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">elif</span> <span class="n">s</span><span class="p">:</span>
<span class="k">return</span> <span class="n">thing</span><span class="o">.</span><span class="vm">__class__</span> <span class="ow">in</span> <span class="p">{</span><span class="n">AnyJoyType</span><span class="p">,</span> <span class="n">StackJoyType</span><span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">a</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="n">b</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="n">s2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a10001</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)}</span> <span class="o">-></span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span> <span class="p">(</span><span class="n">a10001</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">a</span><span class="p">),</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">)</span> <span class="p">[</span><span class="n">a1</span><span class="o">*</span><span class="p">]</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="n">s1</span><span class="p">))</span> <span class="p">[</span><span class="n">a2</span> <span class="n">a1</span><span class="o">*</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">((</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">((</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">)</span>
</pre></div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">f</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]))),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">f</span> <span class="o">=</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">]))),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">)</span>
</pre></div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="o">--</span> <span class="p">[</span><span class="n">n1</span> <span class="n">n2</span> <span class="n">n3</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">sum_</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">sum_</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">f</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span><span class="p">,</span> <span class="s1">'->'</span><span class="p">,</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">sum_</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<div class="section" id="compose-version-3">
<h4><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 3<a class="headerlink" href="#compose-version-3" title="Permalink to this headline">¶</a></h4>
<p>This function has to be modified to yield multiple results.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">compose</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">),</span> <span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">g_in</span><span class="p">,</span> <span class="n">f_out</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">s</span><span class="p">:</span>
<span class="k">yield</span> <span class="n">update</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="p">(</span><span class="n">f_in</span><span class="p">,</span> <span class="n">g_out</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">meta_compose</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
<span class="k">for</span> <span class="n">f</span><span class="p">,</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">product</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">C</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">g</span><span class="p">):</span>
<span class="k">yield</span> <span class="n">delabel</span><span class="p">(</span><span class="n">fg</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="n">muls</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">(</span><span class="n">i1</span> <span class="o">--</span> <span class="n">i2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">dup</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">([</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="n">n1</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">cons</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">MC</span><span class="p">([</span><span class="n">cons</span><span class="p">],</span> <span class="p">[</span><span class="n">sum_</span><span class="p">]):</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">f</span><span class="p">)</span>
</pre></div>
</div>
<span class="p">(</span><span class="n">n1</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">(((</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sum_</span> <span class="o">=</span> <span class="p">(((</span><span class="n">N</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">Ns</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])),</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span> <span class="p">(</span><span class="n">N</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">cons</span><span class="p">),</span>
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">sum_</span><span class="p">),</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span> <span class="p">[</span><span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="n">a1</span> <span class="o">.</span><span class="mf">1.</span><span class="p">])</span> <span class="p">([</span><span class="n">n1</span> <span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n0</span><span class="p">)</span> <span class="p">(</span><span class="n">n1</span> <span class="p">[</span><span class="n">n1</span><span class="o">*</span> <span class="o">.</span><span class="mf">1.</span><span class="p">]</span> <span class="o">--</span> <span class="n">n2</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="p">(</span><span class="n">As</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">])))</span>
<span class="n">a</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a4</span><span class="p">,</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
<span class="n">b</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">a1</span><span class="p">,</span> <span class="p">(</span><span class="n">a2</span><span class="p">,</span> <span class="n">s2</span><span class="p">))</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span>
</pre></div>
</div>
<span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="n">a4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(</span><span class="n">a1</span><span class="o">*</span><span class="p">,</span> <span class="p">(</span><span class="n">a3</span><span class="p">,</span> <span class="n">s1</span><span class="p">)),</span> <span class="n">a2</span><span class="p">:</span> <span class="n">a10003</span><span class="p">}</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">unify</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="nb">print</span> <span class="n">result</span>
</pre></div>
</div>
<p>We need a type variable for Joy functions that can go in our expressions
and be used by the hybrid inferencer/interpreter. They have to store a
name and a list of stack effects.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">FunctionJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">FunctionJoyType</span><span class="p">(</span><span class="n">AnyJoyType</span><span class="p">):</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
<span class="bp">self</span><span class="o">.</span><span class="n">stack_effects</span> <span class="o">=</span> <span class="n">sec</span>
<span class="bp">self</span><span class="o">.</span><span class="n">number</span> <span class="o">=</span> <span class="n">number</span>
- <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="fm">__radd__</span> <span class="o">=</span> <span class="fm">__add__</span>
- <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
</pre></div>
</div>
<h4>Specialized for Simple Functions and Combinators<a class="headerlink" href="#specialized-for-simple-functions-and-combinators" title="Permalink to this headline">¶</a></h4>
<p>For non-combinator functions the stack effects list contains stack
effect comments (represented by pairs of cons-lists as described above.)</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">SymbolJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">SymbolJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
<span class="n">prefix</span> <span class="o">=</span> <span class="s1">'F'</span>
</pre></div>
</div>
<p>For combinators the list contains Python functions.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CombinatorJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">CombinatorJoyType</span><span class="p">(</span><span class="n">FunctionJoyType</span><span class="p">):</span>
<span class="n">prefix</span> <span class="o">=</span> <span class="s1">'C'</span>
- <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">,</span> <span class="n">expect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
+ <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">,</span> <span class="n">expect</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">CombinatorJoyType</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">sec</span><span class="p">,</span> <span class="n">number</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">expect</span> <span class="o">=</span> <span class="n">expect</span>
</div>
<p>For simple combinators that have only one effect (like <code class="docutils literal notranslate"><span class="pre">dip</span></code>) you only
need one function and it can be the combinator itself.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">joy.library</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">joy.library</span>
<span class="n">dip</span> <span class="o">=</span> <span class="n">CombinatorJoyType</span><span class="p">(</span><span class="s1">'dip'</span><span class="p">,</span> <span class="p">[</span><span class="n">joy</span><span class="o">.</span><span class="n">library</span><span class="o">.</span><span class="n">dip</span><span class="p">],</span> <span class="mi">23</span><span class="p">)</span>
</pre></div>
<p>For combinators that can have more than one effect (like <code class="docutils literal notranslate"><span class="pre">branch</span></code>) you
have to write functions that each implement the action of one of the
effects.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">branch_true</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">branch_true</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
<span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="p">(</span><span class="n">else_</span><span class="p">,</span> <span class="p">(</span><span class="n">flag</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span> <span class="o">=</span> <span class="n">stack</span>
<span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">then</span><span class="p">,</span> <span class="n">expression</span><span class="p">),</span> <span class="n">dictionary</span>
updated along with the stack effects after doing unification or we risk
losing useful information. This was a straightforward, if awkward,
modification to the call structure of <code class="docutils literal notranslate"><span class="pre">meta_compose()</span></code> et. al.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">ID</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># Identity function.</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">ID</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># Identity function.</span>
<span class="k">def</span> <span class="nf">infer</span><span class="p">(</span><span class="o">*</span><span class="n">expression</span><span class="p">):</span>
cruft to convert the definitions in <code class="docutils literal notranslate"><span class="pre">DEFS</span></code> to the new
<code class="docutils literal notranslate"><span class="pre">SymbolJoyType</span></code> objects, and some combinators. Here is an example of
output from the current code :</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span> <span class="c1"># (Don't try to run this cell! It's not going to work. This is "read only" code heh..)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">1</span><span class="o">/</span><span class="mi">0</span> <span class="c1"># (Don't try to run this cell! It's not going to work. This is "read only" code heh..)</span>
<span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="nb">format</span><span class="o">=</span><span class="s1">'</span><span class="si">%(message)s</span><span class="s1">'</span><span class="p">,</span> <span class="n">stream</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
actually does some evaluation and explores branching code paths</p>
<p>Work remains to be done:</p>
<ul class="simple">
-<li><p>the rest of the library has to be covered</p></li>
-<li><p>figure out how to deal with <code class="docutils literal notranslate"><span class="pre">loop</span></code> and <code class="docutils literal notranslate"><span class="pre">genrec</span></code>, etc..</p></li>
-<li><p>extend the types to check values (see the appendix)</p></li>
-<li><p>other kinds of “higher order” type variables, OR, AND, etc..</p></li>
-<li><p>maybe rewrite in Prolog for great good?</p></li>
-<li><p>definitions</p></li>
-<li><p>don’t permit composition of functions that don’t compose</p></li>
-<li><p>auto-compile compilable functions</p></li>
-<li><p>Compiling more than just the Yin functions.</p></li>
-<li><p>getting better visibility (than Python debugger.)</p></li>
-<li><p>DOOOOCS!!!! Lots of docs!</p></li>
-<li><p>docstrings all around</p></li>
-<li><p>improve this notebook (it kinda falls apart at the end narratively. I
-went off and just started writing code to see if it would work. It
-does, but now I have to come back and describe here what I did.</p></li>
+<li>the rest of the library has to be covered</li>
+<li>figure out how to deal with <code class="docutils literal notranslate"><span class="pre">loop</span></code> and <code class="docutils literal notranslate"><span class="pre">genrec</span></code>, etc..</li>
+<li>extend the types to check values (see the appendix)</li>
+<li>other kinds of “higher order” type variables, OR, AND, etc..</li>
+<li>maybe rewrite in Prolog for great good?</li>
+<li>definitions<ul>
+<li>don’t permit composition of functions that don’t compose</li>
+<li>auto-compile compilable functions</li>
+</ul>
+</li>
+<li>Compiling more than just the Yin functions.</li>
+<li>getting better visibility (than Python debugger.)</li>
+<li>DOOOOCS!!!! Lots of docs!<ul>
+<li>docstrings all around</li>
+<li>improve this notebook (it kinda falls apart at the end
+narratively. I went off and just started writing code to see if it
+would work. It does, but now I have to come back and describe here
+what I did.</li>
+</ul>
+</li>
</ul>
</div>
<div class="section" id="appendix-joy-in-the-logical-paradigm">
as it were. There’s a working demo of this at the end of the <code class="docutils literal notranslate"><span class="pre">types</span></code>
module. But if you’re interested in all that you should just use Prolog!</p>
<p>Anyhow, type <em>checking</em> is a few easy steps away.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_ge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">_ge</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="k">return</span> <span class="p">(</span><span class="nb">issubclass</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="vm">__class__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
<span class="ow">or</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s1">'accept'</span><span class="p">)</span>
<span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">accept</span><span class="p">))</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">The Blissful Elegance of Typing Joy</a><ul>
+<li><a class="reference internal" href="#part-i-poials-rules">Part I: Pöial’s Rules</a><ul>
+<li><a class="reference internal" href="#first-rule">First Rule</a></li>
+<li><a class="reference internal" href="#second-rule">Second Rule</a></li>
+<li><a class="reference internal" href="#third-rule">Third Rule</a></li>
+<li><a class="reference internal" href="#stack-effect-comments">Stack Effect Comments</a></li>
+<li><a class="reference internal" href="#pop-swap"><code class="docutils literal notranslate"><span class="pre">pop</span> <span class="pre">swap</span></code></a></li>
+<li><a class="reference internal" href="#popswap-roll"><code class="docutils literal notranslate"><span class="pre">pop∘swap</span> <span class="pre">roll<</span></code></a></li>
+<li><a class="reference internal" href="#compiling-popswaproll">Compiling <code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<</span></code></a></li>
+<li><a class="reference internal" href="#functions-on-stacks">Functions on Stacks</a></li>
+<li><a class="reference internal" href="#popswaproll-rest"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<</span> <span class="pre">rest</span></code></a></li>
+<li><a class="reference internal" href="#popswaproll-rest-rest"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest</span> <span class="pre">rest</span></code></a></li>
+<li><a class="reference internal" href="#popswaproll-restrest-cons"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest∘rest</span> <span class="pre">cons</span></code></a></li>
+<li><a class="reference internal" href="#popswaproll-restrestcons-cons"><code class="docutils literal notranslate"><span class="pre">pop∘swap∘roll<∘rest∘rest∘cons</span> <span class="pre">cons</span></code></a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#part-ii-implementation">Part II: Implementation</a><ul>
+<li><a class="reference internal" href="#representing-stack-effect-comments-in-python">Representing Stack Effect Comments in Python</a></li>
+<li><a class="reference internal" href="#compose"><code class="docutils literal notranslate"><span class="pre">compose()</span></code></a></li>
+<li><a class="reference internal" href="#unify"><code class="docutils literal notranslate"><span class="pre">unify()</span></code></a></li>
+<li><a class="reference internal" href="#update"><code class="docutils literal notranslate"><span class="pre">update()</span></code></a></li>
+<li><a class="reference internal" href="#relabel"><code class="docutils literal notranslate"><span class="pre">relabel()</span></code></a></li>
+<li><a class="reference internal" href="#delabel"><code class="docutils literal notranslate"><span class="pre">delabel()</span></code></a></li>
+<li><a class="reference internal" href="#c"><code class="docutils literal notranslate"><span class="pre">C()</span></code></a></li>
+<li><a class="reference internal" href="#stack-functions">Stack Functions</a></li>
+<li><a class="reference internal" href="#dealing-with-cons-and-uncons">Dealing with <code class="docutils literal notranslate"><span class="pre">cons</span></code> and <code class="docutils literal notranslate"><span class="pre">uncons</span></code></a><ul>
+<li><a class="reference internal" href="#unify-version-2"><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 2</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#part-iii-compiling-yin-functions">Part III: Compiling Yin Functions</a><ul>
+<li><a class="reference internal" href="#python-identifiers">Python Identifiers</a></li>
+<li><a class="reference internal" href="#doc-from-stack-effect"><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code></a></li>
+<li><a class="reference internal" href="#compile"><code class="docutils literal notranslate"><span class="pre">compile_()</span></code></a></li>
+<li><a class="reference internal" href="#compiling-library-functions">Compiling Library Functions</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#part-iv-types-and-subtypes-of-arguments">Part IV: Types and Subtypes of Arguments</a><ul>
+<li><a class="reference internal" href="#number-type">“Number” Type</a></li>
+<li><a class="reference internal" href="#distinguishing-numbers">Distinguishing Numbers</a></li>
+<li><a class="reference internal" href="#distinguishing-types">Distinguishing Types</a></li>
+<li><a class="reference internal" href="#typing-sqr">Typing <code class="docutils literal notranslate"><span class="pre">sqr</span></code></a></li>
+<li><a class="reference internal" href="#modifying-the-inferencer">Modifying the Inferencer</a><ul>
+<li><a class="reference internal" href="#delabel-version-2"><code class="docutils literal notranslate"><span class="pre">delabel()</span></code> version 2</a></li>
+<li><a class="reference internal" href="#unify-version-3"><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 3</a></li>
+<li><a class="reference internal" href="#compose-dup-and-mul">Compose <code class="docutils literal notranslate"><span class="pre">dup</span></code> and <code class="docutils literal notranslate"><span class="pre">mul</span></code></a></li>
+<li><a class="reference internal" href="#compile-version-2"><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 2</a></li>
+<li><a class="reference internal" href="#compilable"><code class="docutils literal notranslate"><span class="pre">compilable()</span></code></a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#part-v-functions-that-use-the-stack">Part V: Functions that use the Stack</a><ul>
+<li><a class="reference internal" href="#stackuncons"><code class="docutils literal notranslate"><span class="pre">stack∘uncons</span></code></a></li>
+<li><a class="reference internal" href="#stackunconsuncons"><code class="docutils literal notranslate"><span class="pre">stack∘uncons∘uncons</span></code></a><ul>
+<li><a class="reference internal" href="#compose-version-2"><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 2</a></li>
+</ul>
+</li>
+<li><a class="reference internal" href="#doc-from-stack-effect-version-2"><code class="docutils literal notranslate"><span class="pre">doc_from_stack_effect()</span></code> version 2</a><ul>
+<li><a class="reference internal" href="#compile-version-3"><code class="docutils literal notranslate"><span class="pre">compile_()</span></code> version 3</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#part-vi-multiple-stack-effects">Part VI: Multiple Stack Effects</a><ul>
+<li><a class="reference internal" href="#representing-an-unbounded-sequence-of-types">Representing an Unbounded Sequence of Types</a><ul>
+<li><a class="reference internal" href="#unify-version-4"><code class="docutils literal notranslate"><span class="pre">unify()</span></code> version 4</a></li>
+<li><a class="reference internal" href="#compose-version-3"><code class="docutils literal notranslate"><span class="pre">compose()</span></code> version 3</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#part-vii-typing-combinators">Part VII: Typing Combinators</a><ul>
+<li><a class="reference internal" href="#hybrid-inferencer-interpreter">Hybrid Inferencer/Interpreter</a><ul>
+<li><a class="reference internal" href="#joy-types-for-functions">Joy Types for Functions</a></li>
+<li><a class="reference internal" href="#specialized-for-simple-functions-and-combinators">Specialized for Simple Functions and Combinators</a></li>
+<li><a class="reference internal" href="#infer"><code class="docutils literal notranslate"><span class="pre">infer()</span></code></a></li>
+<li><a class="reference internal" href="#work-in-progress">Work in Progress</a></li>
+</ul>
+</li>
+</ul>
+</li>
+<li><a class="reference internal" href="#conclusion">Conclusion</a></li>
+<li><a class="reference internal" href="#appendix-joy-in-the-logical-paradigm">Appendix: Joy in the Logical Paradigm</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Types.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Traversing Datastructures with Zippers — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="The Blissful Elegance of Typing Joy" href="Types.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="traversing-datastructures-with-zippers">
Huet</a></p>
<p>Given a datastructure on the stack we can navigate through it, modify
it, and rebuild it using the “zipper” technique.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
</pre></div>
</div>
<div class="section" id="trees">
<h2>Trees<a class="headerlink" href="#trees" title="Permalink to this headline">¶</a></h2>
<p>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
+(aka lists, aka quoted literals, aka aggregates, etc…), but we can build
<a class="reference external" href="https://en.wikipedia.org/wiki/Tree_%28data_structure%29">trees</a> out
of sequences.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8]'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8]'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
show the trace so you can see how it works. If we were going to use
these a lot it would make sense to write Python versions for efficiency,
but see below.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'z-down == [] swap uncons swap'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'z-down == [] swap uncons swap'</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">'z-up == swons swap shunt'</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">'z-right == [swons] cons dip uncons swap'</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">'z-left == swons [uncons swap] dip swap'</span><span class="p">)</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] z-down'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] z-down'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="n">z</span><span class="o">-</span><span class="n">down</span>
<span class="p">[]</span> <span class="p">[[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="mi">1</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[] [[2 [3 4 25 6] 7] 8] 1 z-right'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[] [[2 [3 4 25 6] 7] 8] 1 z-right'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="mi">1</span> <span class="n">z</span><span class="o">-</span><span class="n">right</span>
<span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 25 6] 7] z-down'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 25 6] 7] z-down'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">2</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [] [[3 4 25 6] 7] 2 z-right'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [] [[3 4 25 6] 7] 2 z-right'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 25 6] z-down'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 25 6] z-down'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">3</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [] [4 25 6] 3 z-right'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [] [4 25 6] 3 z-right'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">4</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3] [25 6] 4 z-right'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3] [25 6] 4 z-right'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">25</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 25 sqr'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 25 sqr'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">625</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 625 z-up'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 625 z-up'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">625</span> <span class="n">z</span><span class="o">-</span><span class="n">up</span>
<span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 625 6] z-up'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 625 6] z-up'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span>
</pre></div>
</div>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 625 6] 7] z-up'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 625 6] 7] z-up'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
<h2><code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code><a class="headerlink" href="#dip-and-infra" title="Permalink to this headline">¶</a></h2>
<p>In Joy we have the <code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code> combinators which can “target”
or “address” any particular item in a Joy tree structure.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="p">[[[[[[</span><span class="n">sqr</span><span class="p">]</span> <span class="n">dipd</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">infra</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">Z</span></code> function isn’t hard to make.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Z == [[] cons cons] step i'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Z == [[] cons cons] step i'</span><span class="p">)</span>
</pre></div>
</div>
<p>Here it is in action in a simplified scenario.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [2 3 4] Z'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [2 3 4] Z'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span> <span class="n">Z</span>
</pre></div>
</div>
<p>And here it is doing the main thing.</p>
-<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z'</span><span class="p">)</span>
+<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z'</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2 current"><a class="current reference internal" href="#">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
+ <h3><a href="../index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Traversing Datastructures with Zippers</a><ul>
+<li><a class="reference internal" href="#trees">Trees</a></li>
+<li><a class="reference internal" href="#zipper-in-joy">Zipper in Joy</a></li>
+<li><a class="reference internal" href="#dip-and-infra"><code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code></a></li>
+<li><a class="reference internal" href="#z"><code class="docutils literal notranslate"><span class="pre">Z</span></code></a></li>
+<li><a class="reference internal" href="#addressing">Addressing</a></li>
+<li><a class="reference internal" href="#determining-the-right-path-for-an-item-in-a-tree">Determining the right “path” for an item in a tree.</a></li>
</ul>
</li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/Zipper.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Essays about Programming in Joy — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
- <script src="../_static/jquery.js"></script>
- <script src="../_static/underscore.js"></script>
- <script src="../_static/doctools.js"></script>
- <script src="../_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="../_static/documentation_options.js"></script>
+ <script type="text/javascript" src="../_static/jquery.js"></script>
+ <script type="text/javascript" src="../_static/underscore.js"></script>
+ <script type="text/javascript" src="../_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Developing a Program in Joy" href="Developing.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="essays-about-programming-in-joy">
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="Types.html#part-i-poial-s-rules">Part I: Pöial’s Rules</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Types.html#part-i-poials-rules">Part I: Pöial’s Rules</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html#part-ii-implementation">Part II: Implementation</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html#part-iii-compiling-yin-functions">Part III: Compiling Yin Functions</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html#part-iv-types-and-subtypes-of-arguments">Part IV: Types and Subtypes of Arguments</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#brzozowski-s-derivatives-of-regular-expressions">Brzozowski’s Derivatives of Regular Expressions</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#brzozowskis-derivatives-of-regular-expressions">Brzozowski’s Derivatives of Regular Expressions</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#implementation">Implementation</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#let-s-try-it-out">Let’s try it out…</a></li>
+<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#lets-try-it-out">Let’s try it out…</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#larger-alphabets">Larger Alphabets</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#state-machine">State Machine</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#reversing-the-derivatives-to-generate-matching-strings">Reversing the Derivatives to Generate Matching Strings</a></li>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="../index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Essays about Programming in Joy</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
-<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
-<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
-<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
-<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
-</ul>
-</li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="../_sources/notebooks/index.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Parsing Text into Joy Expressions — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Tracing Joy Execution" href="pretty.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="parsing-text-into-joy-expressions">
symbol. Function symbols are unquoted strings and cannot contain square
brackets. Terms must be separated by blanks, which can be omitted
around square brackets.</p>
-<dl class="py exception">
+<dl class="exception">
<dt id="joy.parser.ParseError">
-<em class="property">exception </em><code class="sig-prename descclassname">joy.parser.</code><code class="sig-name descname">ParseError</code><a class="reference internal" href="_modules/joy/parser.html#ParseError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.parser.ParseError" title="Permalink to this definition">¶</a></dt>
+<em class="property">exception </em><code class="descclassname">joy.parser.</code><code class="descname">ParseError</code><a class="reference internal" href="_modules/joy/parser.html#ParseError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.parser.ParseError" title="Permalink to this definition">¶</a></dt>
<dd><p>Raised when there is a error while parsing text.</p>
</dd></dl>
-<dl class="py class">
+<dl class="class">
<dt id="joy.parser.Symbol">
-<em class="property">class </em><code class="sig-prename descclassname">joy.parser.</code><code class="sig-name descname">Symbol</code><a class="reference internal" href="_modules/joy/parser.html#Symbol"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.parser.Symbol" title="Permalink to this definition">¶</a></dt>
+<em class="property">class </em><code class="descclassname">joy.parser.</code><code class="descname">Symbol</code><a class="reference internal" href="_modules/joy/parser.html#Symbol"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.parser.Symbol" title="Permalink to this definition">¶</a></dt>
<dd><p>A string class that represents Joy function names.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.parser.text_to_expression">
-<code class="sig-prename descclassname">joy.parser.</code><code class="sig-name descname">text_to_expression</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">text</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/parser.html#text_to_expression"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.parser.text_to_expression" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.parser.</code><code class="descname">text_to_expression</code><span class="sig-paren">(</span><em>text</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/parser.html#text_to_expression"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.parser.text_to_expression" title="Permalink to this definition">¶</a></dt>
<dd><p>Convert a string to a Joy expression.</p>
<p>When supplied with a string this function returns a Python datastructure
that represents the Joy datastructure described by the text expression.
Any unbalanced square brackets will raise a ParseError.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><p><strong>text</strong> (<em>str</em>) – Text to convert.</p>
-</dd>
-<dt class="field-even">Return type</dt>
-<dd class="field-even"><p>stack</p>
-</dd>
-<dt class="field-odd">Raises</dt>
-<dd class="field-odd"><p><a class="reference internal" href="#joy.parser.ParseError" title="joy.parser.ParseError"><strong>ParseError</strong></a> – if the parse fails.</p>
-</dd>
-</dl>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>text</strong> (<em>str</em>) – Text to convert.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">stack</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Raises:</th><td class="field-body"><a class="reference internal" href="#joy.parser.ParseError" title="joy.parser.ParseError"><strong>ParseError</strong></a> – if the parse fails.</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Parsing Text into Joy Expressions</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#module-joy.parser"><code class="docutils literal notranslate"><span class="pre">joy.parser</span></code></a></li>
-<li class="toctree-l2"><a class="reference internal" href="#parser-internals">Parser Internals</a></li>
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Parsing Text into Joy Expressions</a><ul>
+<li><a class="reference internal" href="#module-joy.parser"><code class="docutils literal notranslate"><span class="pre">joy.parser</span></code></a></li>
+<li><a class="reference internal" href="#parser-internals">Parser Internals</a></li>
</ul>
</li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="_sources/parser.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tracing Joy Execution — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Function Reference" href="library.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="tracing-joy-execution">
<p>On each line the stack is printed with the top to the right, then a <code class="docutils literal notranslate"><span class="pre">.</span></code> to
represent the current locus of processing, then the pending expression to the
left.</p>
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.pretty_print.TracePrinter">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.pretty_print.</code><code class="sig-name descname">TracePrinter</code><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter" title="Permalink to this definition">¶</a></dt>
+<em class="property">class </em><code class="descclassname">joy.utils.pretty_print.</code><code class="descname">TracePrinter</code><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter" title="Permalink to this definition">¶</a></dt>
<dd><p>This is what does the formatting. You instantiate it and pass the <code class="docutils literal notranslate"><span class="pre">viewer()</span></code>
method to the <a class="reference internal" href="joy.html#joy.joy.joy" title="joy.joy.joy"><code class="xref py py-func docutils literal notranslate"><span class="pre">joy.joy.joy()</span></code></a> function, then print it to see the
trace.</p>
-<dl class="py method">
+<dl class="method">
<dt id="joy.utils.pretty_print.TracePrinter.go">
-<code class="sig-name descname">go</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter.go"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter.go" title="Permalink to this definition">¶</a></dt>
+<code class="descname">go</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter.go"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter.go" title="Permalink to this definition">¶</a></dt>
<dd><p>Return a list of strings, one for each entry in the history, prefixed
with enough spaces to align all the interpreter dots.</p>
<p>This method is called internally by the <code class="docutils literal notranslate"><span class="pre">__str__()</span></code> method.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Return type</dt>
-<dd class="field-odd"><p>list(str)</p>
-</dd>
-</dl>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">list(str)</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="py method">
+<dl class="method">
<dt id="joy.utils.pretty_print.TracePrinter.viewer">
-<code class="sig-name descname">viewer</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter.viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter.viewer" title="Permalink to this definition">¶</a></dt>
+<code class="descname">viewer</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#TracePrinter.viewer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.TracePrinter.viewer" title="Permalink to this definition">¶</a></dt>
<dd><p>Record the current stack and expression in the TracePrinter’s history.
Pass this method as the <code class="docutils literal notranslate"><span class="pre">viewer</span></code> argument to the <a class="reference internal" href="joy.html#joy.joy.joy" title="joy.joy.joy"><code class="xref py py-func docutils literal notranslate"><span class="pre">joy.joy.joy()</span></code></a> function.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><ul class="simple">
-<li><p><strong>quote</strong> (<em>stack</em>) – A stack.</p></li>
-<li><p><strong>expression</strong> (<em>stack</em>) – A stack.</p></li>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
+<li><strong>quote</strong> (<em>stack</em>) – A stack.</li>
+<li><strong>expression</strong> (<em>stack</em>) – A stack.</li>
</ul>
-</dd>
-</dl>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.pretty_print.trace">
-<code class="sig-prename descclassname">joy.utils.pretty_print.</code><code class="sig-name descname">trace</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#trace"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.trace" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.pretty_print.</code><code class="descname">trace</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#trace"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.trace" title="Permalink to this definition">¶</a></dt>
<dd><p>Evaluate a Joy expression on a stack and print a trace.</p>
<p>This function is just like the <cite>i</cite> combinator but it also prints a
trace of the evaluation</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><ul class="simple">
-<li><p><strong>stack</strong> (<em>stack</em>) – The stack.</p></li>
-<li><p><strong>expression</strong> (<em>stack</em>) – The expression to evaluate.</p></li>
-<li><p><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</p></li>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>stack</strong> (<em>stack</em>) – The stack.</li>
+<li><strong>expression</strong> (<em>stack</em>) – The expression to evaluate.</li>
+<li><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</li>
</ul>
-</dd>
-<dt class="field-even">Return type</dt>
-<dd class="field-even"><p>(stack, (), dictionary)</p>
-</dd>
-</dl>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">(stack, (), dictionary)</p>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Tracing Joy Execution</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#module-joy.utils.pretty_print"><code class="docutils literal notranslate"><span class="pre">joy.utils.pretty_print</span></code></a></li>
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Tracing Joy Execution</a><ul>
+<li><a class="reference internal" href="#module-joy.utils.pretty_print"><code class="docutils literal notranslate"><span class="pre">joy.utils.pretty_print</span></code></a></li>
</ul>
</li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="_sources/pretty.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Python Module Index — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Search — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
-
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
- <script src="_static/searchtools.js"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/searchtools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="#" />
- <script src="searchindex.js" defer></script>
+ <script type="text/javascript">
+ jQuery(function() { Search.loadIndex("searchindex.js"); });
+ </script>
+
+ <script type="text/javascript" id="searchindexloader"></script>
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<h1 id="search-documentation">Search</h1>
<div id="fallback" class="admonition warning">
- <script>$('#fallback').hide();</script>
+ <script type="text/javascript">$('#fallback').hide();</script>
<p>
Please activate JavaScript to enable the search
functionality.
</p>
</div>
<p>
- Searching for multiple words only shows matches that contain
- all words.
+ From here you can search these documents. Enter your search
+ words into the box below and click "search". Note that the search
+ function will automatically search for all of the words. Pages
+ containing fewer words won't appear in the result list.
</p>
<form action="" method="get">
- <input type="text" name="q" aria-labelledby="search-documentation" value="" />
+ <input type="text" name="q" value="" />
<input type="submit" value="search" />
<span id="search-progress" style="padding-left: 10px"></span>
</form>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
-</ul>
-
-<div class="relations">
+ <div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
</ul></li>
</ul>
</div>
-
-
-
-
-
-
-
-
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Derivatives_of_Regular_Expressions","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Recursion_Combinators","notebooks/Replacing","notebooks/The_Four_Operations","notebooks/Treestep","notebooks/TypeChecking","notebooks/Types","notebooks/Zipper","notebooks/index","parser","pretty","stack","types"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":2,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Derivatives_of_Regular_Expressions.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Recursion_Combinators.rst","notebooks/Replacing.rst","notebooks/The_Four_Operations.rst","notebooks/Treestep.rst","notebooks/TypeChecking.rst","notebooks/Types.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst","types.rst"],objects:{"joy.joy":{joy:[1,1,1,""],repl:[1,1,1,""],run:[1,1,1,""]},"joy.library":{"void":[3,1,1,""],BinaryBuiltinWrapper:[3,1,1,""],DefinitionWrapper:[3,2,1,""],FunctionWrapper:[3,1,1,""],SimpleFunctionWrapper:[3,1,1,""],UnaryBuiltinWrapper:[3,1,1,""],add_aliases:[3,1,1,""],app1:[3,1,1,""],app2:[3,1,1,""],app3:[3,1,1,""],b:[3,1,1,""],branch:[3,1,1,""],choice:[3,1,1,""],clear:[3,1,1,""],cmp_:[3,1,1,""],concat_:[3,1,1,""],cond:[3,1,1,""],dip:[3,1,1,""],dipd:[3,1,1,""],dipdd:[3,1,1,""],disenstacken:[3,1,1,""],divmod_:[3,1,1,""],drop:[3,1,1,""],dupdip:[3,1,1,""],floor:[3,1,1,""],genrec:[3,1,1,""],getitem:[3,1,1,""],help_:[3,1,1,""],i:[3,1,1,""],id_:[3,1,1,""],infer_:[3,1,1,""],infra:[3,1,1,""],initialize:[3,1,1,""],inscribe:[3,1,1,""],inscribe_:[3,1,1,""],loop:[3,1,1,""],map_:[3,1,1,""],max_:[3,1,1,""],min_:[3,1,1,""],parse:[3,1,1,""],pm:[3,1,1,""],pred:[3,1,1,""],remove:[3,1,1,""],reverse:[3,1,1,""],select:[3,1,1,""],sharing:[3,1,1,""],shunt:[3,1,1,""],sort_:[3,1,1,""],sqrt:[3,1,1,""],step:[3,1,1,""],succ:[3,1,1,""],sum_:[3,1,1,""],take:[3,1,1,""],times:[3,1,1,""],unique:[3,1,1,""],warranty:[3,1,1,""],words:[3,1,1,""],x:[3,1,1,""],yin_functions:[3,1,1,""],zip_:[3,1,1,""]},"joy.library.DefinitionWrapper":{add_def:[3,3,1,""],add_definitions:[3,3,1,""],parse_definition:[3,3,1,""]},"joy.parser":{ParseError:[21,4,1,""],Symbol:[21,2,1,""],text_to_expression:[21,1,1,""]},"joy.utils":{generated_library:[3,0,0,"-"],pretty_print:[22,0,0,"-"],stack:[23,0,0,"-"],types:[24,0,0,"-"]},"joy.utils.generated_library":{ccons:[3,1,1,""],cons:[3,1,1,""],dup:[3,1,1,""],dupd:[3,1,1,""],dupdd:[3,1,1,""],first:[3,1,1,""],first_two:[3,1,1,""],fourth:[3,1,1,""],over:[3,1,1,""],pop:[3,1,1,""],popd:[3,1,1,""],popdd:[3,1,1,""],popop:[3,1,1,""],popopd:[3,1,1,""],popopdd:[3,1,1,""],rest:[3,1,1,""],rolldown:[3,1,1,""],rollup:[3,1,1,""],rrest:[3,1,1,""],second:[3,1,1,""],stack:[3,1,1,""],stuncons:[3,1,1,""],stununcons:[3,1,1,""],swaack:[3,1,1,""],swap:[3,1,1,""],swons:[3,1,1,""],third:[3,1,1,""],tuck:[3,1,1,""],uncons:[3,1,1,""],unit:[3,1,1,""],unswons:[3,1,1,""]},"joy.utils.pretty_print":{TracePrinter:[22,2,1,""],trace:[22,1,1,""]},"joy.utils.pretty_print.TracePrinter":{go:[22,3,1,""],viewer:[22,3,1,""]},"joy.utils.stack":{concat:[23,1,1,""],expression_to_string:[23,1,1,""],iter_stack:[23,1,1,""],list_to_stack:[23,1,1,""],pick:[23,1,1,""],stack_to_string:[23,1,1,""]},"joy.utils.types":{AnyJoyType:[24,2,1,""],AnyStarJoyType:[24,2,1,""],BooleanJoyType:[24,2,1,""],CombinatorJoyType:[24,2,1,""],FloatJoyType:[24,2,1,""],FloatStarJoyType:[24,2,1,""],FunctionJoyType:[24,2,1,""],IntJoyType:[24,2,1,""],IntStarJoyType:[24,2,1,""],JoyTypeError:[24,4,1,""],KleeneStar:[24,2,1,""],NumberJoyType:[24,2,1,""],NumberStarJoyType:[24,2,1,""],StackJoyType:[24,2,1,""],StackStarJoyType:[24,2,1,""],SymbolJoyType:[24,2,1,""],TextJoyType:[24,2,1,""],TextStarJoyType:[24,2,1,""],compilable:[24,1,1,""],compile_:[24,1,1,""],compose:[24,1,1,""],delabel:[24,1,1,""],doc_from_stack_effect:[24,1,1,""],infer:[24,1,1,""],meta_compose:[24,1,1,""],poly_compose:[24,1,1,""],reify:[24,1,1,""],relabel:[24,1,1,""],type_check:[24,1,1,""],uni_unify:[24,1,1,""]},"joy.utils.types.AnyStarJoyType":{kind:[24,5,1,""]},"joy.utils.types.BooleanJoyType":{accept:[24,5,1,""]},"joy.utils.types.FloatJoyType":{accept:[24,5,1,""]},"joy.utils.types.FloatStarJoyType":{kind:[24,5,1,""]},"joy.utils.types.IntJoyType":{accept:[24,5,1,""]},"joy.utils.types.IntStarJoyType":{kind:[24,5,1,""]},"joy.utils.types.KleeneStar":{kind:[24,5,1,""]},"joy.utils.types.NumberStarJoyType":{kind:[24,5,1,""]},"joy.utils.types.StackJoyType":{accept:[24,5,1,""]},"joy.utils.types.StackStarJoyType":{kind:[24,5,1,""]},"joy.utils.types.TextJoyType":{accept:[24,5,1,""]},"joy.utils.types.TextStarJoyType":{kind:[24,5,1,""]},joy:{joy:[1,0,0,"-"],library:[3,0,0,"-"],parser:[21,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","method","Python method"],"4":["py","exception","Python exception"],"5":["py","attribute","Python attribute"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:method","4":"py:exception","5":"py:attribute"},terms:{"05s":5,"0b11100111011011":6,"23rd":18,"4ac":12,"5bkei":11,"9a9d60354c35":18,"\u03b4":5,"\u03b5":9,"abstract":[8,11],"boolean":[2,3,8,11,15],"break":[5,8,18],"byte":[5,6],"case":[2,3,13,15,16,18,23],"char":5,"class":[3,5,8,18,21,22,23,24],"default":[3,7,11,23],"export":[3,21],"final":[2,11,13],"float":[8,18,19,21,24],"function":[0,1,4,6,7,10,12,17,19,20,21,22,23,24],"g\u00e9rard":19,"goto":5,"import":[2,5,6,7,9,11,12,13,14,16,17,18,19],"int":[5,7,8,13,18,19,21,23,24],"long":[11,18,20],"new":[2,3,5,7,8,10,13,14,18,24],"p\u00f6ial":20,"p\u00f6ial06typingtool":18,"public":10,"return":[1,3,5,6,8,11,13,14,15,16,18,21,22,23,24],"static":[2,10],"super":18,"switch":[2,18],"throw":[11,24],"true":[2,3,5,6,13,15,18,24],"try":[7,9,12,13,16,17,18,20],"void":[0,3],"while":[3,5,8,11,18,21,23],AND:[5,18],Adding:[8,14,20],And:[5,6,7,9,11,13,15,18,19,23],But:[0,4,6,7,8,11,14,18],CPS:8,For:[2,3,11,13,14,18,20,23,24],Its:3,NOT:5,Not:18,One:[2,8,15,18,20],REs:5,TOS:[2,3],That:[6,11],The:[0,1,2,3,4,5,7,9,10,12,19,20,21,22,23,24],Then:[2,3,11,12,13,18],There:[5,12,13,15,16,18,23],These:[15,18,20,23,24],Use:[3,9,13],Used:15,Using:[0,9,11,20],With:[9,13,18,20,24],_1000:18,__add__:18,__call__:5,__class__:18,__eq__:18,__ge__:18,__hash__:18,__init__:[5,18],__main__:18,__radd__:18,__repr__:18,__str__:22,_and:5,_compaction_rul:5,_con:5,_dictionari:18,_ge:18,_infer:18,_interpret:18,_log:18,_log_it:18,_names_for:18,_or:5,_templat:5,_to_str:18,_tree_add_:11,_tree_add_e:[11,24],_tree_add_p:11,_tree_add_r:11,_tree_add_t:11,_tree_delete_:11,_tree_delete_clear_stuff:[11,24],_tree_delete_del:11,_tree_delete_r0:[11,24],_tree_delete_r1:11,_tree_delete_rightmost:11,_tree_delete_w:11,_tree_get_:[11,24],_tree_get_p:11,_tree_get_r:11,_tree_get_t:11,_tree_iter_order_curr:11,_tree_iter_order_left:11,_tree_iter_order_r:11,_tree_iter_order_right:11,_tree_t:11,_treestep_0:16,_treestep_1:16,_uniqu:18,_within_b:9,_within_p:9,_within_r:9,a10001:18,a10002:18,a10003:18,a10004:18,a_i:9,abbrevi:16,abl:[5,15,18,24],about:[0,8,11,15,18,19,23],abov:[0,5,6,9,11,13,15,18],abs:9,absolut:8,accept:[1,2,3,5,6,7,8,11,12,14,15,16,18,19,24],accord:5,accordingli:[11,15],accumul:6,act:[5,24],action:[0,8,14,18,19,20],actual:[2,6,8,11,15,18],adapt:20,add:[3,5,6,7,8,14,18,22,24],add_alias:3,add_def:3,add_definit:[3,11,16],added:[4,11],adding:[10,18],addit:[0,2,3,6,8,13,14,16],address:20,adjust:11,advantag:18,affect:[3,15],after:[5,6,7,8,13,15,18,24],afterward:8,again:[2,3,6,8,11,13,18,24],against:[18,24],aggreg:19,ahead:18,aka:[5,8,19,24],albrecht:0,algorithm:[5,8,18],alia:[3,24],alias:[3,8],align:[8,22],all:[3,5,6,7,8,11,13,14,15,16,18,22,24],alloc:18,allow:[10,11,15],almost:11,along:[5,8,13,18,24],alphabet:[3,20],alreadi:[5,9,14,18,19],also:[0,5,6,8,11,15,18,22,23,24],alter:[5,18],altern:[4,18,24],although:[4,11],altogeth:7,alwai:[6,10,13,15],amend:15,among:18,amort:11,analysi:[4,20],anamorph:[8,20],ani:[4,5,6,8,10,11,15,18,19,21,24],annual:8,anonym:11,anoth:[5,11,15,18,23,24],anyhow:[15,18],anyjoytyp:[18,24],anymor:18,anystarjoytyp:[18,24],anyth:[2,3,5,8,18,24],apart:18,api:10,app1:3,app2:[3,8,12,13,14,15],app3:[3,15],app:8,appear:[2,4,5,6,11,24],append:18,appendix:20,appli:[2,3,6,7,11,13,18,24],applic:7,approach:6,appropri:5,approxim:20,archiv:0,aren:19,arg:[2,3],argument:[2,3,8,9,12,13,20,22,23],arithmet:2,ariti:[2,15],around:[6,18,21,23],arrang:16,arriv:[7,16],arrow:5,articl:[0,4,7,13],ascii:5,ascii_lowercas:5,ask:[4,7,18],aspect:0,assembl:5,assert:[5,18],assign:[15,23],associ:11,assum:9,asterisk:16,asterix:[18,24],asyncron:15,attack:8,attempt:[0,1,3,18],attribut:3,attributeerror:18,author:18,auto:[0,18,24],automat:[4,15,18,24],auxiliari:[5,16],avail:[0,18,24],averag:[8,14],avoid:[11,24],awai:[11,18],awar:2,awkward:[11,13,18],azur:20,back:[11,18],backtrack:24,backward:[10,11,12,16],bad:18,bag:8,banana:13,bar:15,barb:13,base:[0,2,3,10,13,16,18],basestr:24,basic:[2,3,8,11],basicconfig:[17,18],becaas:5,becaus:[2,3,5,8,11,15,16,18,19,23,24],becom:[11,16,23],becuas:18,been:[5,9,10,11,18,19],befor:[5,7,8,11],begin:[11,16],behavior:[10,16,24],behaviour:[0,1,18,24],behind:15,being:[0,15,24],below:[2,3,5,6,7,11,18,19],bespok:8,best:0,better:[6,11,13,18],between:[0,6,24],beyond:7,biannual:8,bin:5,binari:[0,7,8,20],binary_search_tre:11,binarybuiltinwrapp:3,bind:8,bingo:19,bit:[5,6,7,11,18],blank:21,bliss:[0,20],block:6,bodi:[2,3,5,8,11,15],body_text:3,booktitl:18,bool:[13,18,24],booleanjoytyp:24,borrow:[8,18],both:[2,6,8,12,13,14,15,18,23],bottom:7,bounce_to:5,bracket:[8,18,21],branch:[3,5,6,7,13,18,20,24],branch_fals:18,branch_tru:18,breakpoint:8,bring:[6,8,18],bruijn:18,brutal:15,brzozowski:[18,20],brzozowskian:5,btree:[11,16],buck:11,bug:[0,8],build:[7,8,12,13,19,23],built:[12,18],builtin:24,bundl:[2,3,13],burgeon:8,calculu:4,call:[1,2,5,8,10,11,13,15,18,22,23],caller:[11,18],can:[0,2,3,4,5,6,7,8,9,10,12,13,14,15,16,18,19,20,21,23,24],cancel:15,cannot:[17,18,21],captur:8,card:8,care:[6,23],carefulli:19,carri:[7,11,24],cartesian:4,catamorph:20,categor:[0,20],categori:[4,15],ccc:4,ccon:[3,11,17,18,24],cell:[13,18],certain:[8,23],certainli:11,chain:[3,15],chang:[2,10,11,18,19],charact:[5,19],chat:8,chatter:[0,18],check:[0,7,9,18,20,24],child:16,choic:[3,13],choos:10,chop:12,chose:5,cinf:11,circl:5,circuit:4,cite_not:11,classmethod:3,claus:[3,18],clean:18,clear:[3,6,8],clear_stuff:11,cleav:[8,12,14],close:[0,1,4],clunki:[6,18],clv:15,cmp:[3,16,20],cmp_:3,code:[0,1,4,5,12,13,15,18,20,24],codireco:[7,9],collaps:13,collect:[4,5,7,8,18],collis:24,combin:[0,3,6,7,8,9,12,15,16,19,20,22,24],combinatorjoytyp:[18,24],come:[8,11,18],command:[8,11,18],comment:[15,24],common:[2,6,15],compar:[3,4,5,18],comparison:[0,11],compat:15,compel:4,compil:[2,3,4,5,8,11,14,15,20,24],compile_:24,complement:5,complet:[3,4],complex:[3,15,18,19,24],complic:18,compos:[5,24],composit:[18,24],compostit:18,compound:11,comput:[2,4,5,6,8,12,15,18,24],con:[3,5,6,7,8,9,11,12,13,15,16,19,23,24],conal:[4,15],concat:[3,7,8,15,16,18,23],concat_:3,concaten:[0,5],concatin:[0,3,5,23],concern:15,conclus:20,concurr:2,cond:[3,11],condit:[3,8],confer:18,conflict:[11,18,24],consecut:20,consid:[5,6,7,11,13,16,18,19],consist:[2,7,8,15,16],constant:11,constitu:13,construct:[15,18],consum:[15,18],contain:[0,2,3,5,7,8,13,18,21],content:18,context:2,conting:11,continu:[0,5,13,18,19],control:8,conveni:[4,15,18],convent:15,convers:18,convert:[13,14,16,18,21,23],cool:11,copi:[2,3,6,11,13,15,16,17,20],copyright:8,correspond:[4,15],could:[2,4,5,6,8,10,11,15,18,19],couldn:15,count:[3,18],counter:[6,18],coupl:16,cours:[6,11,18],cover:18,cpu:15,crack:11,crash:11,creat:[0,2,3,6,9,11,15,18],creativ:18,crude:[11,18,21,24],cruft:18,curent:24,current:[2,3,8,13,15,16,18,19,22,24],curri:5,custom:10,cycl:[6,7],cython:8,d010101:5,d0101:5,d01:5,d10:5,d_compact:5,dai:8,data:[2,3,5,13],datastructur:[0,2,13,18,20,21,23],datatyp:23,ddididi:19,deal:[0,5,11,15],dealt:18,debugg:18,decid:11,declar:18,decor:3,decoupl:13,decrement:3,deduc:[6,18],deeper:0,deepli:4,def:[3,5,8,13,14,18,23],defaultdict:[5,18],defi:3,defin:[2,3,4,5,6,7,8,9,10,12,13,14,15,18,19,20],definit:[0,2,3,6,7,8,10,11,13,16,18,20,24],definitionwrapp:[3,11,13,16],defint:15,del:17,delabel:24,deleg:8,delet:20,deliber:18,demo:18,demonstr:4,depend:[3,11,13,15],deposit:16,depth:[18,24],dequot:13,der:11,deriv:[2,3,6,8,9,11,18,20],derv:5,describ:[3,4,5,11,13,15,16,18,21,24],descript:[6,8],descriptor:18,design:[2,3,11,15,20],desir:[8,16],destin:5,destruct:11,detail:[8,11,18],detect:[5,7,11,13,18],determin:20,develop:[0,7,8,18,20],diagram:6,dialect:1,dict:[1,3,5,18,22,24],dictionari:[0,1,3,8,18,20,22],did:18,differ:[0,4,6,9,11,12,13,15,23],differenti:4,difficult:18,difficulti:15,dig:[11,19],digit:6,digraph:5,dinfrirst:[8,18,24],dip:[3,6,7,8,9,11,12,13,14,15,16,18,20,24],dipd:[3,7,8,11,12,13,15,18,19,24],dipdd:[3,11],direco:20,direct:8,directli:[6,15,16,18,23],disappear:[2,5,18,24],discard:[3,7,9,11,13],disciplin:11,disctionari:1,disenstacken:[3,8],disk:8,displac:2,displai:18,distiguish:18,distribut:15,ditch:11,div:[3,8,18,24],dive:16,divis:[11,18],divmod:[3,24],divmod_:[3,18],doc:[2,3,8,18,24],doc_from_stack_effect:[17,24],docstr:18,document:[18,20,21,23],doe:[0,1,3,4,5,7,8,14,15,18,20,22,24],doesn:[6,10,11,15,16,18,23],doing:[4,6,8,15,18,19],domain:[4,18],don:[5,6,8,11,18,24],done:[2,6,8,10,18],dooooc:18,door:8,dot:[5,22],doubl:[3,5,6,8,18],doublecircl:5,down:[2,5,9,13,19,24],down_to_zero:8,dozen:8,draft:[4,10],dream:8,drive:[7,9],driven:6,driver:[5,7],drop:[3,11],dudipd:8,due:18,dup:[3,6,7,8,9,11,12,13,15,17,19,23,24],dupd:[3,18,24],dupdd:[3,24],dupdip:[3,6,11,12,13],duplic:[3,11,13],durat:2,dure:[2,13],each:[2,3,4,5,6,8,13,14,15,16,18,22,24],easi:[0,11,16,18,19],easier:[3,11,15],easili:4,eat:5,edit:20,effect:[2,3,5,8,15,19,20,24],effici:[7,14,19],efg:18,either:[1,2,3,5,11,13,18],elabor:18,eleg:[0,5,8,11,15,20],element:2,elif:18,elimin:[5,18],elliott:[4,15],els:[2,3,5,13,15,18],else_:18,embed:[4,11,19],emit:18,empti:[3,5,8,16,18,23,24],encapsul:8,enclos:8,encod:7,encount:18,end:[5,6,11,13,16,18,23],endless:7,enforc:[2,8],engend:8,enough:[5,8,13,22,24],enstacken:[7,8,18],enter:[3,8,24],enter_guard:18,entir:23,entri:[3,19,22],enumer:18,epsilon:9,equal:[3,6,16,23],equat:[8,9],equival:15,ergo:[5,11],err:[11,17],error:[8,18,21],essai:0,establish:18,etc:[3,16,18,19,21],euler:20,euro:18,eval:[0,18],evalu:[1,2,3,8,9,11,12,13,14,15,16,18,22],event:15,eventu:[15,18],ever:18,everi:[1,7,15],everybodi:15,everyth:[3,5,11,12,15,18],evolv:10,examin:13,exampl:[0,3,5,6,18,20,21,23,24],exce:7,except:[5,8,11,17,18,21,24],execut:[0,1,2,3,8,13,14,15,16,18,19,23,24],exend:18,exercis:[5,11],exist:[4,11,18],expand:11,expect:[2,3,15,16,18,23,24],experi:[8,16],explain:18,explan:8,explor:[8,18],express:[0,1,2,3,4,11,13,14,18,19,20,22,23],expression_to_str:[18,23],extend:18,extra:[6,7],extract:[11,12,20],extrem:8,extrememli:8,f_g:18,f_in:18,f_out:18,f_python:18,facet:0,facil:8,fact:21,factor:[2,6,8,11,18],factori:20,fail:[2,3,11,20,21,24],fail_fail:3,fairli:18,fake:5,fall:18,fals:[2,3,5,6,13,15,18,24],falsei:18,far:[9,11,13,18,24],fascin:0,favorit:15,fear:[11,18],few:[6,8,9,12,15,18],fewer:[3,8],fg_in:18,fg_out:18,fib:7,fib_gen:7,fibonacci:20,figur:[2,3,11,13,18],filter:11,fin:6,find:[2,3,5,6,7,15,16,18,20],finder:9,fine:[0,5,6,11,18,24],finite_state_machin:5,first:[3,5,7,8,9,11,12,13,14,16,19,20,24],first_two:[3,11,24],fit:[6,8],five:[6,8,20],fix:[2,3,5,13,18,24],fixm:[5,18],flag:[15,18],flatten:[8,16,18],flesh:5,flexibl:20,floatjoytyp:[18,24],floatstarjoytyp:[18,24],floor:3,floordiv:[6,24],flow:8,follow:[0,2,3,5,8,10,13,15,16,18,19,24],foo:[8,10,11,15,18],foo_ii:10,fork:15,form:[2,3,4,5,6,7,13,16,18,23],forman:8,format:[17,18,20,22],formula:[0,6,20],forth:[8,18],forum:0,forward:18,found:8,four:[0,2,3,6,7,8,11,20],fourteen:6,fourth:[2,3,11,13,24],frac:[9,12],fractal:8,fraction0:8,fraction:[2,8],frame:13,framework:8,free:[4,8,11],freeli:2,from:[0,1,2,3,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,23],from_:5,front:[2,3,13],frozenset:5,fulin:15,full:6,fun:[5,20],func:18,functionjoytyp:[18,24],functionwrapp:3,functool:5,fundament:[0,20],funtion:11,further:[9,18,20],futur:15,g_in:18,g_out:18,garbag:8,gari:11,gcd:8,gener:[0,2,4,13,15,18,20,23,24],generated_librari:3,genrec:[3,8,11,13,15,16,18],geometr:6,get:[2,4,5,6,7,8,12,13,18,20],getch:5,getitem:3,getrecursionlimit:23,getsourc:8,ghc:4,give:[4,6,11,13,16,18,23],given:[2,3,6,7,9,11,13,15,18,19,20],global:[17,18],glue:8,goe:24,going:[5,11,12,15,16,18,19],good:[6,11,18],grab:18,grammar:21,grand:8,graph:15,graphic:5,graphviz:5,great:[0,8,18,20],greater:23,grind:18,group:0,grow:5,gsra:9,guard:[11,18,24],had:[5,6,19],haiku:8,half:[6,18,19],hallmark:15,hand:[5,8,14,18,20],handi:[9,18],handl:[11,18,23,24],happen:[8,18],happi:5,hard:[5,18,19],hardwar:4,has:[0,2,5,7,8,9,10,11,13,15,18,19,23],hasattr:18,hash:18,haskel:4,have:[2,3,5,6,7,8,9,10,13,14,15,18,19,20,23,24],haven:24,head:23,heh:18,help:[8,11,13,18],help_:3,helper:[3,5],herd:8,here:[5,6,7,11,16,18,19,24],hide:11,hierarchi:18,higher:[5,8,11,18],highli:8,hij:5,histori:[18,22,24],hit:5,hmm:[5,11],hoist:3,hold:[6,18],hood:11,hope:[0,6,8,20],hopefulli:13,host:20,how:[0,4,5,9,11,13,18,19,20],howev:[13,14,15,18],html:[2,3,7,12,13,20],http:11,huet:19,huge:11,hugh:[9,16],human:8,hybrid:24,hylomorph:20,hypothet:2,id_:3,idea:[4,6,8,18],ident:[3,5,13,18,24],if_not_empti:11,ift:[3,11,13,16,18,24],ignor:[1,3,11,18],iii:20,illustr:[5,13],imagin:[5,15,19],imap:18,imit:[5,16],immedi:[5,13],immut:[5,8,11],imper:13,implement:[0,1,2,3,4,8,10,11,13,14,15,20,24],implementaion:15,implicit:8,improv:18,includ:[4,11,15,16,18,24],inclus:6,incom:23,incompat:10,incorpor:12,increas:6,increment:[3,4,6,10,15],indetermin:24,index:[0,8,18,23],indexerror:23,indic:[15,16,18,24],ineffici:18,infer:[0,3,17],infer_:3,inferenc:24,info:[17,18],inform:[3,5,18,24],infra:[3,7,8,11,12,14,15,16,18,20,24],infrastructur:3,initi:[2,3,5,8,9,11,18],inlin:11,inner:18,inproceed:18,input:[1,9,15,17,18,24],input_:5,inscrib:3,inscribe_:3,insert:18,insight:13,inspect:8,inspect_stack:18,instal:0,instanc:18,instanti:[4,22],instead:[5,6,7,11,13,18,19,23,24],instruct:5,integ:[2,3,8,13,16,18,21],integr:3,intend:[0,8],interact:[8,20],interest:[0,6,11,18,20],interfer:15,interlud:20,intermedi:13,intern:[0,18,22,23],interpret:[0,4,10,14,21,22,24],interrupt:8,intersect:5,interspers:15,interv:[4,6],intjoytyp:[18,24],introduc:10,introduct:0,intstarjoytyp:[18,24],intuit:18,invalid:24,invari:3,invent:18,involv:18,ipf:8,ipython:18,isinst:[5,18],isn:[5,11,19],issubclass:18,item:[2,3,8,11,13,15,16,18,20,23],iter:[1,3,5,8,13,15,16,18,20,23],iter_stack:[14,23],iteritem:[5,18],itertool:[5,18],its:[0,1,2,3,4,6,8,11,13,15,16,18,23],itself:[0,2,8,11,15,18,24],j05cmp:[2,3,13],jaanu:18,jmp:5,job:[15,20],john:[9,16],joi:[2,4,10,11,12,14,15,17],join:[5,18],joypi:[8,19],joytypeerror:[17,24],jump:5,jump_from:5,junk:18,jupyt:20,just:[0,2,3,5,7,8,10,11,13,15,16,18,19,22],juxtaposit:15,keep:[5,11,12,15,18,19],kei:[5,16,20],kevin:0,key_n:11,keyerror:[5,11,18],kind:[2,4,8,11,13,16,18,24],kinda:18,kleen:[16,18,24],kleenestar:[18,24],kleffner:18,know:[6,11,18],knowledg:18,known:[4,15],kstar:5,l_kei:11,l_left:11,l_right:11,l_valu:11,label:[5,18],lambda:[4,5,18],languag:[4,5,8,10,11,14,18],larg:[5,18],larger:[20,23],largest:3,last:[6,11,13,18],lastli:7,later:[5,8,16,18],law:2,lazi:18,lazili:9,lcm:6,lead:[5,8,18,24],leaf:11,lean:8,learn:0,least:[2,6,13,18,23],least_fract:8,leav:[6,15],left:[5,8,12,13,15,16,18,19,22,23,24],leftov:13,legend:5,len:[5,18],length:[3,6,23],lens:13,less:[6,7,8,13,18,23],let:[7,9,11,12,13,16,18,19,20],letter:18,level:[4,5,11,17,18],librari:[0,5,14],like:[2,3,5,6,8,15,16,18,20,21,22,24],limit:[18,24],line:[3,8,11,12,18,22,24],linear:23,link:[0,5,18],linux:0,list:[0,3,5,6,8,9,11,13,15,16,18,19,22,24],list_to_stack:[18,23],liter:[1,11,16,18,19,21],literatur:18,littl:[5,7,11,15,18,20],live:20,lkei:16,load:[6,8],local:18,locat:2,locu:22,log:[17,18],log_2:11,logic:[0,6,20],longer:[11,18],look:[1,5,7,8,9,11,12,15,18],lookup:8,loop:[0,1,3,5,6,18,20,24],lose:18,lot:[5,8,11,18,19],love:6,low:[4,5],lower:6,lowercas:[5,18],lowest:11,lshift:24,machin:[0,20],machineri:[11,18],macro:8,made:[0,8,15,18,19],magic:18,mai:[2,13,15],mail:0,main:[0,3,8,12,15,18,19],mainloop:10,maintain:19,major:10,make:[2,3,4,6,8,11,13,14,15,16,18,19,20],make_gener:9,make_graph:5,manfr:[0,2,3,4,13],mani:[0,5,8,18],manipul:18,manner:12,map:[1,3,5,6,8,10,13,16,18,22],map_:3,marker:8,mask:[6,7],match:[0,1,18,20],materi:0,math:[0,8,9,11,12,18],mathemat:8,matter:[6,9,11,16],max_:3,maximum:3,mayb:[11,18],mean:[3,4,6,8,9,11,13,16,18,23,24],meant:[8,11,13,16],mem:5,member:[2,3,13],memo:5,mental:8,mention:2,mercuri:0,mess:18,messag:[17,18],meta:[8,11,14],meta_compos:[18,24],method:[0,3,8,18,20,22],midpoint:6,might:[4,5,7,11,18],mike:11,million:7,min_:3,mind:18,minimum:3,minor:11,minu:3,mirror:0,miscellan:0,mismatch:18,mix:[8,18],mod:3,mode:18,model:[4,8],modern:0,modif:[7,18],modifi:[8,11,19],modul:[0,1,3,8,18,21],modulo:18,modulu:[8,24],moment:18,month:8,more:[0,3,4,5,6,7,8,9,13,14,15,16,18,21,23,24],most:[5,18,24],mostli:0,move:[5,11],movement:2,much:[5,6,7,11,13,18],muck:11,mul:[3,8,12,17,19,22,24],multi:3,multipl:[20,24],must:[2,3,6,10,13,15,16,18,21],myself:18,n10001:18,n10002:18,n10003:18,n1001:18,n1002:18,n1003:18,name:[1,3,5,8,10,11,13,18,19,20,21,22,23,24],narr:18,natur:[5,6,7,11,18],navig:19,nearli:18,neat:11,neato:18,necessarili:18,need:[2,3,6,7,9,10,11,13,15,18],neg:[3,12,24],neither:[15,18],ness:5,nest:[3,8,11,19],network:8,never:[5,10,13],new_def:18,new_f:18,new_fo:18,new_kei:11,new_valu:11,newton:[0,20],next:[5,6,15,16,18,24],nice:[0,5,13,23],niether:2,node:[5,16,20],node_kei:11,node_valu:11,non:[5,16,18,24],none:[1,3,18,24],nope:16,nor:5,normal:15,notat:[8,11],note:[2,5,6,9,11,13,15,18,23],notebook:[6,7,8,18,19,20],notebook_preambl:[2,6,7,9,11,12,13,14,16,18,19],noth:[2,11,15],notic:6,now:[5,6,7,8,13,14,16,18,20],nth:[3,23],nullari:[8,11,15,18,24],number:[1,2,3,6,7,9,15,23,24],numberjoytyp:[18,24],numberstarjoytyp:[18,24],numer:18,object:[5,18,21],observ:6,obviou:7,obvious:18,occur:11,odd:[6,7],off:[2,3,6,7,12,18,19],often:[5,15],old:[2,14],old_k:11,old_kei:11,old_valu:11,omg:5,omit:[13,18,21],onc:[3,5,10,11],one:[2,3,5,6,7,11,13,15,16,18,22,23,24],ones:[5,7,18],onli:[2,3,5,6,11,13,15,18,19,23,24],onto:[1,2,3,8,13,23],open:[8,18],oper:[0,3,5,8,11,13,20,23],oppos:18,optim:11,option:[1,8,11,18,23],orchestr:15,order:[0,2,3,8,13,15,17,18,20,23],org:[0,11],origin:[0,1,2,3,11,19],other:[0,2,3,4,5,8,11,13,16,18,23,24],otherwis:[3,5,6,7,11,16,18,24],our:[5,6,7,8,9,13,16,18],out:[2,3,4,6,7,8,9,11,12,13,15,18,19,20],outcom:16,outlin:5,output:[5,9,13,15,17,18,24],outsid:4,over:[3,4,6,7,8,9,11,12,15,16,18,20,24],overhaul:18,overview:18,own:[11,18],pack:23,packag:[0,8],page:[0,11,18,23],pair:[2,3,6,7,11,18],palidrom:6,palindrom:6,pam:8,paper:[4,8,13,15,19],paradigm:20,parallel:[2,20],paramet:[1,2,3,13,14,21,22,23],parameter:20,paramorph:13,parenthes:[11,23],pariti:7,pars:[0,3,5,8],parse_definit:3,parseerror:21,parser:[0,17,18],part:[2,3,9,13,16,20],partial:[5,18],particular:19,pass:[0,5,11,18,22,24],past:24,patch:5,path:[5,18,20],pattern:[5,6,15,16,20],pe1:[6,7],pe2:7,pearl:19,pend:[3,8,13,18,19,22],peopl:20,per:[8,16],perfectli:15,perform:[5,15,18],perhap:7,period:8,permit:[15,18,23],permut:18,persist:[3,11],phase:2,phi:5,pick:[6,7,15,23],pickl:8,pictur:11,piec:13,pip:0,place:[3,6,8,18],plai:0,plu:3,plug:[7,13,16],point:[4,5,8,11,13,15],pointless:2,poly_compos:24,pool:15,pop:[3,5,6,7,8,11,13,14,16,17,23,24],popd:[3,8,9,11,14,15,18,24],popdd:[3,7,12,18,24],popop:[3,6,7,8,9,11,16,18,24],popopd:[3,24],popopdd:[3,24],posit:[3,6,8,13],possibilit:11,possibl:[11,16,18,20],post:8,poswrd:18,potenti:15,pow:24,power:[8,18],pprint:5,pragmat:6,preambl:9,preceed:15,precis:[0,1],pred:[3,18,24],predic:[2,3,5,7,13,15,24],prefix:[18,22],preliminari:5,present:18,preserv:[4,16],pretti:[9,11,12,15,16,18,22,23],pretty_print:0,previou:[8,15],prime:9,primit:[2,3,18,20],primrec:[7,8,9,13],print:[0,1,2,3,5,17,18,22,23,24],probabl:[7,8,11,18],problem:[8,18,20],proc_curr:11,proc_left:11,proc_right:11,proce:[6,24],process:[5,8,16,18,22],produc:[6,11,13,16,18],product:[5,7,8,17,18],program:[0,2,3,7,8,9,11,13,15,18,19,24],programm:[15,18],progress:15,project:20,prolog:18,promis:15,prompt:8,proper:[2,3,13,15,24],properti:0,provid:[0,3,4,8,15,18,24],pun:[0,8],punctuat:18,pure:[0,5],puriti:8,purpos:8,push:[2,3,8,13,19,23],put:[1,2,7,8,15,18,20,23],pypi:0,python:[0,2,3,5,11,13,15,19,20,21,23,24],quadrat:[0,20],queri:[11,16],query_kei:16,queu:13,quit:[0,16],quot:[0,3,7,8,11,12,13,15,16,18,19,22,24],quotat:[2,3,13],quotient:3,r_kei:11,r_left:11,r_right:11,r_valu:11,rais:[5,11,18,21,23],rang:[5,8,18],range_revers:13,range_to_zero:8,ranger:13,ranger_revers:13,rankdir:5,raphson:9,rather:[6,8,13,16],ratio:8,reach:[5,6,7,13],read:[0,1,6,7,11,18,19],readabl:14,reader:[5,11],readi:18,real:11,realiz:[4,11],rearrang:[2,3,11,18],reason:[6,8,15,18],rebuild:[16,19],rec1:[2,3,13],rec2:[2,3,13],recent:18,recogn:21,recombin:15,record:[8,22],recur:[13,18],recurs:[0,2,3,5,7,8,9,15,18,20,23],recus:8,redefin:20,redistribut:[3,8],redo:5,reduc:[2,18],redund:23,refactor:[8,10],refer:[0,2],referenti:15,reflect:15,regard:15,regist:2,regular:[18,20,21],reifi:[17,24],reimplement:[15,20],relabel:24,relat:[5,18],releas:10,remain:[2,8,10,18],remaind:[3,9],rememb:5,remind:18,remov:[3,11,18,23],render:20,repeat:6,repeatedli:6,repetit:5,repl:[0,1],replac:[0,2,3,7,12,13,15,16,18,19,20,23],repositori:0,repr:[5,18],repres:[2,8,11,15,21,22,24],represent:[23,24],reprod:7,repurpos:18,requir:[15,18,23],res:18,research:18,resembl:8,resolut:15,resourc:[3,15],respect:[5,6,15],rest:[3,6,7,8,11,13,19,20,23,24],rest_two:11,restart:3,restor:2,result:[1,2,3,5,6,11,12,13,15,16,18,19],resum:8,retir:2,retri:8,reus:[11,18],revers:[3,6,7,13,18,19,20,23],revisit:18,rewrit:[3,8,18],rewritten:8,rid:11,right:[7,8,12,16,18,20,22,23,24],rightest:11,rightmost:6,rigor:15,risk:18,rkei:16,rob:18,roll:[3,9,11,16],roll_dn:18,rolldown:[3,17,18,24],rollup:[3,18,24],root:[3,9,12],round:18,row:5,rrest:[3,17,18,24],rshift:24,rule:[15,20],run:[0,1,3,6,8,9,11,12,13,15,16,18,19],runtim:15,runtimeerror:23,sai:[5,7,11,12,16,18],same:[2,4,6,11,15,18,23],sandwich:[2,3,13],save:[2,5,6,8],scan:3,scanner:[8,21],scenario:19,scope:[7,11],search:[0,11],sec:[18,24],second:[3,8,11,13,16,23,24],section:13,see:[0,5,7,8,9,10,12,13,14,18,19,22],seem:[0,6,8,16,18,24],seen:[18,19,24],select:3,self:[5,15,18],semant:[2,3,8,10,11,15,18],semi:8,send:8,sens:[0,2,6,18,19],separ:[8,15,18,21],seq:18,sequenc:[0,1,2,3,6,8,11,13,14,19,20,21,24],sequence_to_stack:18,seri:[6,7,11,19],ses:18,set:[2,3,5,13,18,20],seven:[6,7],sever:[0,4,8,13],shape:[5,15],share:[3,8],shelf:2,shew:5,shift:[6,7],shorter:20,shorthand:11,should:[2,3,5,6,11,13,15,18],shouldn:8,show:[4,15,18,19],shunt:[3,19],side:[5,11,17,18,24],sign:3,signatur:24,signifi:[8,11],similar:[11,16,18],simon:8,simpl:[5,8,13,23,24],simplefunctionwrapp:[3,14,18],simpler:16,simplest:[18,20],simpli:4,simplifi:[6,11,19],sinc:[2,6,11,18],singl:[3,7,8,14,15,18,21,24],singleton:5,situ:11,situat:11,six:[6,7,8],sixti:[6,7],size:[5,8,20],skeptic:8,skip:18,slight:9,slightli:[11,13,18],smallest:3,smart:11,softwar:8,solei:2,solut:[6,7],solvabl:8,some:[2,3,5,7,8,11,13,15,16,18,20,23,24],somehow:[11,18],someth:[2,10,11,18],sometim:11,somewher:[11,20],sort:[3,5,11,15,18],sort_:3,sourc:[0,1,3,18,20,21,22,23,24],space:[6,22],span:6,spawn:18,special:[7,11,20],specif:[0,4],specifi:[11,15,24],speed:14,spell:[5,16],sphinx:[20,23],spirit:[0,1,16],split:[5,18,24],sqr:[3,8,9,12,19],sqrt:[3,9,18,24],squar:[3,9,18,21],stack:[0,1,3,6,7,9,11,12,13,14,15,16,17,19,20,21,22,24],stack_effect:18,stack_effect_com:18,stack_to_str:[17,23],stacki:18,stackjoytyp:[18,24],stackstarjoytyp:[18,24],stage:16,stai:[0,1],stand:[4,5],standard:[8,11],star:[16,18,24],stare:11,start:[5,6,7,8,9,11,13,16,18,24],state:[8,20],state_nam:5,statement:[3,5],stdout:[17,18],step:[3,6,8,11,14,18,19,20],still:[5,11,18],stop:11,stopiter:5,storag:[6,11],store:[6,13,18],stori:13,str:[1,5,18,21,22,23],straightforward:[5,7,9,18,20],stream:[6,17,18],stretch:11,string:[1,2,3,8,18,19,20,21,22,23,24],stringi:5,structur:[8,15,16,18,19,20,23],stuck:5,studi:5,stuff:[11,18],stuncon:[3,24],stununcon:[3,24],style:[0,4,18],sub:[10,15,24],subclass:8,subject:[15,19],subsequ:15,subset:[18,24],substitut:[5,11,18,24],subtract:6,subtyp:20,succ:[3,18,24],succe:18,success:9,suck:18,suffic:18,suffici:11,suffix:18,suggest:[4,5,11],suitabl:[3,4,6],sum:[3,7,8,12,13,14,16],sum_:[3,18],summand:6,sumtre:16,suppli:[11,21],support:[8,18,22,23],sure:15,suspect:2,svg:5,swaack:[3,12,14,18,19,24],swap:[3,6,7,8,9,11,13,14,15,16,17,19,24],swon:[3,7,8,13,16,18,19,24],swoncat:[7,8,9,13,16],swuncon:13,sym:5,symbol:[1,2,3,5,15,18,19,20,21],symboljoytyp:[18,24],symmetr:[6,11],symmetri:5,syntact:8,syntax:[8,23],sys:[17,18,23],system:[8,11,15],tabl:[5,18],tag:[5,18],tail:[11,18,20,23],tailrec:3,take:[3,5,6,8,9,11,13,15,18,23],talk:[8,11,18,23],target:19,tast:4,tbd:8,tear:13,technic:2,techniqu:[4,19],technolog:2,temporari:19,ten:6,term:[1,2,5,8,9,13,15,18,20,21,23,24],termin:[2,3,5,13],ternari:8,test:[2,3,13],text:[0,1,3,18],text_to_express:[8,17,21],textjoytyp:24,textstarjoytyp:24,textual:8,than:[0,3,5,6,7,8,9,13,15,16,18,23,24],thei:[2,3,5,6,7,8,11,13,15,18,19,21,23,24],them:[2,3,5,6,7,11,13,15,18,19,20,24],themselv:[15,18,24],theori:[2,3,13,15],therefor:7,thi:[0,1,2,3,4,5,6,7,8,9,12,13,15,16,18,19,20,21,22,23,24],thing:[2,7,11,13,15,18,19,21,23,24],think:[2,6,8,11,13,15,16,18],third:[3,7,8,11,24],thirti:6,those:[2,3,5,11,13,18,20,24],though:[6,15],thought:[8,15],thousand:6,thread:[2,15],three:[2,3,5,6,8,11,12,16,18,20],through:[1,6,8,16,18,19,23,24],thun:[2,3,4,10,13,15],thunder:8,thunk:15,time:[3,5,6,8,9,11,13,15,18,19],titl:18,to_check:5,to_set:11,todai:8,todo:[8,21],togeth:[7,8,15,18,20],token:21,toler:20,too:[5,13,18],tool:[8,18],tooo:18,top:[2,3,8,13,18,22,23],total:6,tower:18,trace:[0,8,12,13,19,20,23],traceback:18,traceprint:22,track:[12,18,19],tracker:0,transform:4,transit:5,translat:[4,12,18],trap:5,travers:[0,20],treasur:0,treat:[0,2,3,13,18,20],treatment:7,tree:[0,8,20],treegrind:20,treestep:[0,20],tri:6,triangl:15,triangular_numb:13,trick:[6,18],tricki:18,trinari:24,trobe:0,trove:0,truediv:24,truthi:[3,8,15,18],tuck:[3,8,18,24],tupl:[3,5,8,18,23,24],turn:[2,3,5,18,24],twice:[11,13],two:[2,3,6,8,9,11,12,13,15,16,17,18,19,20,23,24],txt:3,type:[0,1,4,8,11,13,15,20,21,22,23],type_check:24,typeerror:18,typeless:18,typic:[2,3,12,13],unari:8,unarybuiltinwrapp:3,unbalanc:[11,21],unbound:24,unchang:11,uncompil:18,uncon:[3,7,8,11,13,16,19,24],under:[2,3,8,11],underli:[5,15,18],underscor:18,understand:[0,11],undistinguish:11,undocu:8,unfinish:5,unfortun:23,uni_unifi:24,unicod:18,unif:[18,20],unifi:[17,24],union:5,uniqu:[3,5,11,18],unit:[3,8,13,15,24],univers:[0,8,15,18,24],unlik:15,unnecessari:20,unnecesssari:18,unpack:[2,3,11,23],unpair:6,unquot:[8,16,21],unrol:5,unstack:18,unswon:[3,24],untangl:13,until:[5,7,15],unus:6,unusu:11,unwrap:5,updat:[0,17,20,24],uppercas:5,upward:15,usag:8,use:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,19,20,23],used:[3,4,8,11,13,15,18,19,21,23,24],useful:[0,15,18],user:16,uses:[2,5,6,13],using:[7,11,12,13,16,19,24],usual:[0,2,13],util:[0,3,14,17,18],valid:18,valu:[0,1,2,3,6,8,9,12,13,14,15,16,18,20,21,23,24],value_n:11,valueerror:[5,18,23],variabl:[18,20,24],variant:11,variat:[13,15,20],varieti:[4,8],variou:0,vener:23,verbos:4,veri:[0,1,4,5,8,11,23],versa:[2,18],version:[0,1,2,5,7,10,16,19,20],via:8,vice:[2,18],view:[11,20],viewer:[1,8,10,22],vii:20,visibl:18,von:[0,2,3,4,13],waaaai:5,wai:[0,2,3,4,5,6,8,13,14,15,18],wait:15,want:[2,3,6,7,9,11,13,18],warranti:[3,8],wash:8,wast:8,web:23,websit:[0,6],welcom:8,well:[0,4,8,9,11,18,21],went:18,were:[8,18,19],what:[2,3,4,5,8,11,13,15,16,18,22],whatev:[2,3,13,16,23],when:[6,7,8,11,13,15,18,19,21,23,24],where:[2,3,5,8,11,13,18,20,23],whether:13,which:[0,1,5,6,8,9,11,13,15,16,18,19,21,23,24],whole:[2,3,6,13,16,18],whose:7,why:[9,15,16],wiki:11,wikipedia:[0,11,19],wildli:8,wind:8,wire:13,within:[8,11,14,20],without:[2,8,11,12,15,18],won:[11,18,23],word:[0,3,6,8,13,19],work:[0,3,5,6,7,8,9,11,12,13,15,16,19,20,23,24],worker:15,worri:15,worth:6,would:[2,6,7,8,9,11,13,15,18,19,23,24],wrap:[3,8],wrapper:18,write:[4,5,9,11,13,15,16,18,19,20,23],written:[0,1,9,11,14,18,23],wrong:2,wrote:18,xrang:18,yang:18,yeah:15,year:[8,18],yet:[11,15,18,19,24],yield:[2,3,13,18,23,24],yin:[3,20],yin_funct:3,you:[0,2,3,5,6,7,8,10,11,12,13,14,15,16,18,19,22,23],your:[2,3,8,13,18],yourself:[5,8,11],zero:[3,5,11,13,15,16,18,21,23,24],zerodivisionerror:18,zip:[5,6,18],zip_:3,zipper:[0,20],zstr:19},titles:["Thun 0.3.0 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","\u2202RE","Developing a Program in Joy","Using <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Recursion Combinators","Replacing Functions in the Dictionary","The Four Fundamental Operations of Definite Action","Treating Trees II: <code class=\"docutils literal notranslate\"><span class=\"pre\">treestep</span></code>","Type Checking","The Blissful Elegance of Typing Joy","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026","Type Inference of Joy Expressions"],titleterms:{"\u03bb":5,"\u03d5":5,"case":[9,11],"function":[2,3,5,8,9,11,13,14,15,16,18],"long":14,"new":11,"p\u00f6ial":18,"try":5,"void":2,"while":[2,15],Adding:11,One:[7,11],The:[6,8,11,13,15,16,18],There:8,Using:7,With:[5,16],about:20,action:15,add:[2,11],adding:11,address:19,alphabet:5,altern:16,ana:13,analysi:6,anamorph:[2,13],app1:2,app2:2,app3:2,appendix:[11,13,18],appli:15,approxim:9,argument:18,auto:3,averag:2,base:[9,11],binari:[2,11,16],bliss:18,both:11,branch:[2,11,15],brzozowski:5,can:11,cata:13,catamorph:13,categor:4,chatter:2,check:17,child:11,choic:2,clear:2,cleav:[2,15],cmp:11,code:[8,11],combin:[2,11,13,18],comment:18,compact:5,compar:11,comparison:2,compil:[7,18],compile_:18,compos:18,comput:9,con:[2,18],concat:2,conclus:[13,18],consecut:9,continu:8,current:11,datastructur:[5,8,11,19],deal:18,defin:[11,16],definit:[12,15],delabel:18,delet:11,deriv:[5,12,13,16],design:13,determin:19,develop:6,diagram:5,dialect:0,dictionari:14,dip:[2,19],dipd:2,dipdd:2,direco:7,disenstacken:2,distinguish:18,div:2,doc_from_stack_effect:18,document:0,doe:11,down_to_zero:2,drive:5,drop:2,dup:[2,18],dupd:2,dupdip:2,effect:18,eleg:18,els:11,empti:11,enstacken:2,equal:11,essai:20,euler:[6,7],eval:8,even:7,exampl:[2,8,11,13,16,17],execut:22,explor:5,express:[5,8,21,24],extract:16,factori:13,fail:17,fibonacci:7,filter:6,find:[9,11,13],finish:15,finit:5,first:[2,6,15,18],five:7,flatten:2,flexibl:16,floordiv:2,formula:12,found:11,four:[13,15],fsm:5,fulmin:15,fun:13,fundament:15,further:6,gcd:2,gener:[3,5,6,7,9],genrec:2,get:[11,16],getitem:2,given:16,greater:11,group:2,handl:15,have:[11,16],help:2,highest:11,host:0,how:[6,7],hybrid:18,hylo:13,hylomorph:13,identifi:18,ift:[2,15],iii:18,implement:[5,18],indic:0,infer:[18,24],inferenc:18,inform:0,infra:[2,19],integ:6,interest:7,interlud:11,intern:21,interpret:[1,8,18],item:19,iter:[6,11],joi:[0,1,3,6,8,13,18,19,20,21,22,23,24],join:15,just:6,kei:11,kind:15,languag:0,larger:5,least_fract:2,left:11,less:11,let:[5,6],letter:5,librari:[3,8,18],like:11,list:[2,23],literari:8,littl:6,logic:[2,18],loop:[2,8,15],lower:11,lshift:2,machin:5,make:[7,9],mani:6,map:[2,15],match:5,math:2,memoiz:5,method:9,min:2,miscellan:2,mod:2,modifi:18,modulu:2,more:11,most:11,mul:[2,18],multipl:[6,7,18],must:11,name:12,neg:2,newton:9,next:9,node:11,non:11,now:11,nullari:2,nulli:5,number:[13,18],one:8,onli:8,oper:15,order:[11,16],osdn:0,other:15,our:11,out:5,over:2,pack:6,pam:[2,15],para:13,paradigm:18,parallel:15,parameter:[11,16],pars:[2,21],parser:[8,21],part:18,pass:8,path:19,pattern:13,per:11,pop:[2,18],popd:2,popop:2,pow:2,power:7,pred:2,predic:[6,9,11,16],pretty_print:22,primit:13,primrec:2,print:8,problem:[6,7],process:11,product:2,program:[4,6,12,16,20],progress:18,project:[0,6,7],pure:8,put:[11,12,16],python:[8,14,18],quadrat:12,quick:0,quot:[2,23],rang:[2,6,13],range_to_zero:2,read:8,recur:[9,11],recurs:[11,13,16],redefin:[11,16],refactor:[6,11],refer:3,regular:[5,8],reimplement:16,relabel:18,rem:2,remaind:2,remov:2,render:6,repl:8,replac:[11,14],repres:[5,18],represent:5,reset:7,rest:[2,18],revers:[2,5,17],right:[11,19],rightmost:11,roll:[2,18],rolldown:2,rollup:2,rshift:2,rule:[5,18],run:[2,7],second:[2,18],select:2,sequenc:[7,15,18,23],set:[9,11],shorter:14,should:8,shunt:2,simpl:18,simplest:6,size:[2,14],sourc:11,special:[13,18],sqr:[2,18],sqrt:[2,12],stack:[2,8,18,23],start:0,state:5,step:[2,13,16],straightforward:12,stream:5,string:5,structur:11,style:8,sub:[2,11],subtyp:18,succ:2,sum:[2,6],swaack:2,swap:[2,18],swon:2,swoncat:2,symbol:[8,13],tabl:0,tail:13,take:2,term:[6,7,16],ternari:2,text:21,than:11,them:12,thi:11,third:[2,18],three:7,thun:[0,8],time:[2,7],togeth:[11,12,16],token:8,toler:9,trace:[14,22],traceprint:8,trampolin:5,travers:[11,16,19],treat:[11,16],tree:[11,16,19],treegrind:16,treestep:16,triangular:13,truediv:2,truthi:2,tuck:2,two:[5,7],type:[17,18,24],unari:2,unbound:18,uncon:[2,18],unif:17,unifi:18,unit:2,unnecessari:6,unquot:2,unstack:2,updat:[10,18],use:18,util:[22,23,24],valu:[7,11],variabl:12,variat:7,version:[6,11,14,18],view:8,vii:18,within:9,word:2,work:[17,18],write:12,xor:2,yin:18,zero:7,zip:2,zipper:19}})
\ No newline at end of file
+Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Derivatives_of_Regular_Expressions","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Recursion_Combinators","notebooks/Replacing","notebooks/The_Four_Operations","notebooks/Treestep","notebooks/TypeChecking","notebooks/Types","notebooks/Zipper","notebooks/index","parser","pretty","stack","types"],envversion:52,filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Derivatives_of_Regular_Expressions.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Recursion_Combinators.rst","notebooks/Replacing.rst","notebooks/The_Four_Operations.rst","notebooks/Treestep.rst","notebooks/TypeChecking.rst","notebooks/Types.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst","types.rst"],objects:{"joy.joy":{joy:[1,1,1,""],repl:[1,1,1,""],run:[1,1,1,""]},"joy.library":{"void":[3,1,1,""],BinaryBuiltinWrapper:[3,1,1,""],DefinitionWrapper:[3,2,1,""],FunctionWrapper:[3,1,1,""],SimpleFunctionWrapper:[3,1,1,""],UnaryBuiltinWrapper:[3,1,1,""],add_aliases:[3,1,1,""],app1:[3,1,1,""],app2:[3,1,1,""],app3:[3,1,1,""],b:[3,1,1,""],branch:[3,1,1,""],choice:[3,1,1,""],clear:[3,1,1,""],cmp_:[3,1,1,""],concat_:[3,1,1,""],cond:[3,1,1,""],dip:[3,1,1,""],dipd:[3,1,1,""],dipdd:[3,1,1,""],disenstacken:[3,1,1,""],divmod_:[3,1,1,""],drop:[3,1,1,""],dupdip:[3,1,1,""],floor:[3,1,1,""],genrec:[3,1,1,""],getitem:[3,1,1,""],help_:[3,1,1,""],i:[3,1,1,""],id_:[3,1,1,""],infer_:[3,1,1,""],infra:[3,1,1,""],initialize:[3,1,1,""],inscribe:[3,1,1,""],inscribe_:[3,1,1,""],loop:[3,1,1,""],map_:[3,1,1,""],max_:[3,1,1,""],min_:[3,1,1,""],parse:[3,1,1,""],pm:[3,1,1,""],pred:[3,1,1,""],primrec:[3,1,1,""],remove:[3,1,1,""],reverse:[3,1,1,""],select:[3,1,1,""],sharing:[3,1,1,""],shunt:[3,1,1,""],sort_:[3,1,1,""],sqrt:[3,1,1,""],step:[3,1,1,""],succ:[3,1,1,""],sum_:[3,1,1,""],take:[3,1,1,""],times:[3,1,1,""],unique:[3,1,1,""],warranty:[3,1,1,""],words:[3,1,1,""],x:[3,1,1,""],yin_functions:[3,1,1,""],zip_:[3,1,1,""]},"joy.library.DefinitionWrapper":{add_def:[3,3,1,""],add_definitions:[3,3,1,""],parse_definition:[3,3,1,""]},"joy.parser":{ParseError:[21,4,1,""],Symbol:[21,2,1,""],text_to_expression:[21,1,1,""]},"joy.utils":{generated_library:[3,0,0,"-"],pretty_print:[22,0,0,"-"],stack:[23,0,0,"-"],types:[24,0,0,"-"]},"joy.utils.generated_library":{ccons:[3,1,1,""],cons:[3,1,1,""],dup:[3,1,1,""],dupd:[3,1,1,""],dupdd:[3,1,1,""],first:[3,1,1,""],first_two:[3,1,1,""],fourth:[3,1,1,""],over:[3,1,1,""],pop:[3,1,1,""],popd:[3,1,1,""],popdd:[3,1,1,""],popop:[3,1,1,""],popopd:[3,1,1,""],popopdd:[3,1,1,""],rest:[3,1,1,""],rolldown:[3,1,1,""],rollup:[3,1,1,""],rrest:[3,1,1,""],second:[3,1,1,""],stack:[3,1,1,""],stuncons:[3,1,1,""],stununcons:[3,1,1,""],swaack:[3,1,1,""],swap:[3,1,1,""],swons:[3,1,1,""],third:[3,1,1,""],tuck:[3,1,1,""],uncons:[3,1,1,""],unit:[3,1,1,""],unswons:[3,1,1,""]},"joy.utils.pretty_print":{TracePrinter:[22,2,1,""],trace:[22,1,1,""]},"joy.utils.pretty_print.TracePrinter":{go:[22,5,1,""],viewer:[22,5,1,""]},"joy.utils.stack":{concat:[23,1,1,""],expression_to_string:[23,1,1,""],iter_stack:[23,1,1,""],list_to_stack:[23,1,1,""],pick:[23,1,1,""],stack_to_string:[23,1,1,""]},"joy.utils.types":{AnyJoyType:[24,2,1,""],BooleanJoyType:[24,2,1,""],CombinatorJoyType:[24,2,1,""],FloatJoyType:[24,2,1,""],FunctionJoyType:[24,2,1,""],IntJoyType:[24,2,1,""],JoyTypeError:[24,4,1,""],KleeneStar:[24,2,1,""],NumberJoyType:[24,2,1,""],StackJoyType:[24,2,1,""],SymbolJoyType:[24,2,1,""],TextJoyType:[24,2,1,""],compilable:[24,1,1,""],compile_:[24,1,1,""],compose:[24,1,1,""],delabel:[24,1,1,""],doc_from_stack_effect:[24,1,1,""],infer:[24,1,1,""],meta_compose:[24,1,1,""],poly_compose:[24,1,1,""],reify:[24,1,1,""],relabel:[24,1,1,""],type_check:[24,1,1,""],uni_unify:[24,1,1,""]},"joy.utils.types.BooleanJoyType":{accept:[24,6,1,""]},"joy.utils.types.FloatJoyType":{accept:[24,6,1,""]},"joy.utils.types.IntJoyType":{accept:[24,6,1,""]},"joy.utils.types.KleeneStar":{kind:[24,6,1,""]},"joy.utils.types.StackJoyType":{accept:[24,6,1,""]},"joy.utils.types.TextJoyType":{accept:[24,6,1,""]},joy:{joy:[1,0,0,"-"],library:[3,0,0,"-"],parser:[21,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","classmethod","Python class method"],"4":["py","exception","Python exception"],"5":["py","method","Python method"],"6":["py","attribute","Python attribute"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:classmethod","4":"py:exception","5":"py:method","6":"py:attribute"},terms:{"05s":5,"0b11100111011011":6,"23rd":18,"5bkei":11,"9a9d60354c35":18,"\u03b4":5,"\u03b5":9,"abstract":[8,11],"boolean":[2,3,8,11,15],"break":[5,8,18],"byte":[5,6],"case":[2,3,13,15,16,18,23],"char":5,"class":[3,5,8,18,21,22,23,24],"default":[3,7,11,23],"export":[3,21],"final":[2,11,13],"float":[3,8,18,19,21,24],"function":[0,1,4,6,7,10,12,17,19,20,21,22,23,24],"g\u00e9rard":19,"goto":5,"import":[2,5,6,7,9,11,12,13,14,16,17,18,19],"int":[5,7,8,13,18,19,21,23,24],"long":[11,18,20],"new":[2,3,5,7,8,10,13,14,18,24],"p\u00f6ial":20,"p\u00f6ial06typingtool":18,"public":10,"return":[1,3,5,6,8,11,13,14,15,16,18,21,22,23,24],"static":[2,10],"super":18,"switch":[2,18],"throw":[11,24],"true":[2,3,5,6,13,15,18,24],"try":[7,9,12,13,16,17,18,20],"void":[0,3],"while":[3,5,8,11,18,21,23],AND:[5,18],Adding:[8,14,20],And:[5,6,7,9,11,13,15,18,19,23],But:[0,4,6,7,8,11,14,18],CPS:8,For:[2,3,11,13,14,18,20,23,24],Its:3,NOT:5,Not:18,One:[2,8,15,18,20],REs:5,TOS:[2,3],That:[6,11],The:[0,1,2,3,4,5,7,9,10,12,19,20,21,22,23,24],Then:[2,3,11,12,13,18],There:[5,12,13,15,16,18,23],These:[15,18,20,23,24],Use:[3,9,13],Used:15,Using:[0,9,11,20],With:[9,13,18,20,24],_1000:18,__add__:18,__builtin__:24,__call__:5,__class__:18,__eq__:18,__ge__:18,__hash__:18,__init__:[5,18],__main__:18,__radd__:18,__repr__:18,__str__:22,_and:5,_compaction_rul:5,_con:5,_dictionari:18,_ge:18,_infer:18,_interpret:18,_log:18,_log_it:18,_names_for:18,_or:5,_templat:5,_to_str:18,_tree_add_:11,_tree_add_e:[11,24],_tree_add_p:11,_tree_add_r:11,_tree_add_t:11,_tree_delete_:11,_tree_delete_clear_stuff:[11,24],_tree_delete_del:11,_tree_delete_r0:[11,24],_tree_delete_r1:11,_tree_delete_rightmost:11,_tree_delete_w:11,_tree_get_:[11,24],_tree_get_p:11,_tree_get_r:11,_tree_get_t:11,_tree_iter_order_curr:11,_tree_iter_order_left:11,_tree_iter_order_r:11,_tree_iter_order_right:11,_tree_t:11,_treestep_0:16,_treestep_1:16,_uniqu:18,_within_b:9,_within_p:9,_within_r:9,a10001:18,a10002:18,a10003:18,a10004:18,abbrevi:16,abl:[5,15,18,24],about:[0,8,11,15,18,19,23],abov:[0,5,6,9,11,13,15,18],abs:9,absolut:8,accept:[1,2,3,5,6,7,8,11,12,14,15,16,18,19,24],accord:5,accordingli:[11,15],accumul:6,act:[5,24],action:[0,8,14,18,19,20],actual:[2,6,8,11,15,18],adapt:20,add:[3,5,6,7,8,14,18,22,24],add_alias:3,add_def:3,add_definit:[3,11,16],added:[4,11],adding:[10,18],addit:[0,2,3,6,8,13,14,16],address:20,adjust:11,advantag:18,affect:[3,15],after:[5,6,7,8,13,15,18,24],afterward:8,again:[2,3,6,8,11,13,18,24],against:[18,24],aggreg:19,ahead:18,aka:[5,8,19,24],albrecht:0,algorithm:[5,8,18],alia:[3,24],alias:[3,8],align:[8,22],all:[3,5,6,7,8,11,13,14,15,16,18,22,24],alloc:18,allow:[10,11,15],almost:11,along:[5,8,13,18,24],alphabet:[3,20],alreadi:[5,9,14,18,19],also:[0,5,6,8,11,15,18,22,23,24],alter:[5,18],altern:[4,18,24],although:[4,11],altogeth:7,alwai:[6,10,13,15],amend:15,among:18,amort:11,analysi:[4,20],anamorph:[8,20],ani:[4,5,6,8,10,11,15,18,19,21,24],annual:8,anonym:11,anoth:[5,11,15,18,23,24],anyhow:[15,18],anyjoytyp:[18,24],anymor:18,anystarjoytyp:18,anyth:[2,3,5,8,18,24],apart:18,api:10,app1:3,app2:[3,8,12,13,14,15],app3:[3,15],app:8,appear:[2,4,5,6,11,24],append:18,appendix:20,appli:[2,3,6,7,11,13,18,24],applic:7,approach:6,appropri:5,approxim:20,archiv:0,aren:19,arg:[2,3],argument:[2,3,8,9,12,13,20,22,23],arithmet:2,ariti:[2,15],around:[6,18,21,23],arrang:16,arriv:[7,16],arrow:5,articl:[0,4,7,13],ascii:5,ascii_lowercas:5,ask:[4,7,18],aspect:0,assembl:5,assert:[5,18],assign:[15,23],associ:11,assum:9,asterisk:16,asterix:[18,24],asyncron:15,attack:8,attempt:[0,1,3,18],attribut:3,attributeerror:18,author:18,auto:[0,18,24],automat:[4,15,18,24],auxiliari:[5,16],avail:[0,18,24],averag:[8,14],avoid:[11,24],awai:[11,18],awar:2,awkward:[11,13,18],azur:20,back:[3,11,18],backtrack:24,backward:[10,11,12,16],bad:18,bag:8,banana:13,bar:15,barb:13,base:[0,2,3,10,13,16,18],basestr:24,basic:[2,3,8,11],basicconfig:[17,18],becaas:5,becaus:[2,3,5,8,11,15,16,18,19,23,24],becom:[11,16,23],becuas:18,been:[5,9,10,11,18,19],befor:[5,7,8,11],begin:[11,16],behavior:[10,16,24],behaviour:[0,1,18,24],behind:15,being:[0,15,24],below:[2,3,5,6,7,11,18,19],bespok:8,best:0,better:[6,11,13,18],between:[0,6,24],beyond:7,biannual:8,bin:5,binari:[0,7,8,20],binary_search_tre:11,binarybuiltinwrapp:3,bind:8,bingo:19,bit:[5,6,7,11,18],blank:21,bliss:[0,20],block:6,bodi:[2,3,5,8,11,15],body_text:3,booktitl:18,bool:[13,18,24],booleanjoytyp:24,borrow:[8,18],both:[2,6,8,12,13,14,15,18,23],bottom:7,bounce_to:5,bracket:[8,18,21],branch:[3,5,6,7,13,18,20,24],branch_fals:18,branch_tru:18,breakpoint:8,bring:[6,8,18],bruijn:18,brutal:15,brzozowski:[18,20],brzozowskian:5,btree:[11,16],buck:11,bug:[0,8],build:[7,8,12,13,19,23],built:[12,18],bundl:[2,3,13],burgeon:8,calculu:4,call:[1,2,5,8,10,11,13,15,18,22,23],caller:[11,18],can:[0,2,3,4,5,6,7,8,9,10,12,13,14,15,16,18,19,20,21,23,24],cancel:15,cannot:[17,18,21],captur:8,card:8,care:[6,23],carefulli:19,carri:[7,11,24],cartesian:4,catamorph:20,categor:[0,20],categori:[4,15],ccc:4,ccon:[3,11,17,18,24],cell:[13,18],certain:[8,23],certainli:11,chain:[3,15],chang:[2,10,11,18,19],charact:[5,19],chat:8,chatter:[0,18],check:[0,7,9,18,20,24],child:16,choic:[3,13],choos:10,chop:12,chose:5,cinf:11,circl:5,circuit:4,cite_not:11,classmethod:3,claus:[3,18],clean:18,clear:[3,6,8],clear_stuff:11,cleav:[8,12,14],close:[0,1,4],clunki:[6,18],clv:15,cmp:[3,16,20],cmp_:3,code:[0,1,4,5,12,13,15,18,20,24],codireco:[7,9],collaps:13,collect:[4,5,7,8,18],collis:24,combin:[0,3,6,7,8,9,12,15,16,19,20,22,24],combinatorjoytyp:[18,24],come:[8,11,18],command:[8,11,18],comment:[15,24],common:[2,6,15],compar:[3,4,5,18],comparison:[0,11],compat:15,compel:4,compil:[2,3,4,5,8,11,14,15,20,24],compile_:24,complement:5,complet:[3,4],complex:[3,15,18,19,24],complic:18,compos:[5,24],composit:[18,24],compostit:18,compound:11,comput:[2,4,5,6,8,12,15,18,24],con:[3,5,6,7,8,9,11,12,13,15,16,19,23,24],conal:[4,15],concat:[3,7,8,15,16,18,23],concat_:3,concaten:[0,5],concatin:[0,3,5,23],concern:15,conclus:20,concurr:2,cond:[3,11],condit:[3,8],confer:18,conflict:[11,18,24],consecut:20,consid:[5,6,7,11,13,16,18,19],consist:[2,7,8,15,16],constant:11,constitu:13,construct:[15,18],consum:[15,18],contain:[0,2,3,5,7,8,13,18,21],content:18,context:2,conting:11,continu:[0,5,13,18,19],control:8,conveni:[4,15,18],convent:15,convers:18,convert:[13,14,16,18,21,23],cool:11,copi:[2,3,6,11,13,15,16,17,20],copyright:8,correspond:[4,15],could:[2,4,5,6,8,10,11,15,18,19],couldn:15,count:[3,18],counter:[6,18],coupl:16,cours:[6,11,18],cover:18,cpu:15,crack:11,crash:11,creat:[0,2,3,6,9,11,15,18],creativ:18,crude:[11,18,21,24],cruft:18,curent:24,current:[2,3,8,13,15,16,18,19,22,24],curri:5,custom:10,cycl:[6,7],cython:8,d010101:5,d0101:5,d01:5,d10:5,d_compact:5,dai:8,data:[2,3,5,13],datastructur:[0,2,13,18,20,21,23],datatyp:23,ddididi:19,deal:[0,5,11,15],dealt:18,debugg:18,decid:11,declar:18,decor:3,decoupl:13,decrement:3,deduc:[6,18],deeper:0,deepli:4,def:[3,5,8,13,14,18,23],defaultdict:[5,18],defi:3,defin:[2,3,4,5,6,7,8,9,10,12,13,14,15,18,19,20],definit:[0,2,3,6,7,8,10,11,13,16,18,20,24],definitionwrapp:[3,11,13,16],defint:15,del:17,delabel:24,deleg:8,delet:20,deliber:18,demo:18,demonstr:4,depend:[3,11,13,15],deposit:16,depth:[18,24],dequot:13,der:11,deriv:[2,3,6,8,9,11,18,20],derv:5,describ:[3,4,5,11,13,15,16,18,21,24],descript:[6,8],descriptor:18,design:[2,3,11,15,20],desir:[8,16],destin:5,destruct:11,detail:[8,11,18],detect:[5,7,11,13,18],determin:20,develop:[0,7,8,18,20],diagram:6,dialect:1,dict:[1,3,5,18,22,24],dictionari:[0,1,3,8,18,20,22],did:18,differ:[0,4,6,9,11,12,13,15,23],differenti:4,difficult:18,difficulti:15,dig:[11,19],digit:6,digraph:5,dinfrirst:[8,18,24],dip:[3,6,7,8,9,11,12,13,14,15,16,18,20,24],dipd:[3,7,8,11,12,13,15,18,19,24],dipdd:[3,11],direco:20,direct:8,directli:[6,15,16,18,23],disappear:[2,5,18,24],discard:[3,7,9,11,13],disciplin:11,disctionari:1,disenstacken:[3,8],disk:8,displac:2,displai:18,distiguish:18,distribut:15,ditch:11,div:[3,8,18,24],dive:16,divis:[11,18],divmod:[3,24],divmod_:[3,18],doc:[2,3,8,18,24],doc_from_stack_effect:[17,24],docstr:18,document:[18,20,21,23],doe:[0,1,3,4,5,7,8,14,15,18,20,22,24],doesn:[6,10,11,15,16,18,23],doing:[4,6,8,15,18,19],domain:[4,18],don:[5,6,8,11,18,24],done:[2,6,8,10,18],dooooc:18,door:8,dot:[5,22],doubl:[3,5,6,8,18],doublecircl:5,down:[2,5,9,13,19,24],down_to_zero:8,dozen:8,draft:[4,10],dream:8,drive:[7,9],driven:6,driver:[5,7],drop:[3,11],dudipd:8,due:18,dup:[3,6,7,8,9,11,12,13,15,17,19,23,24],dupd:[3,18,24],dupdd:[3,24],dupdip:[3,6,11,12,13],duplic:[3,11,13],durat:2,dure:[2,13],each:[2,3,4,5,6,8,13,14,15,16,18,22,24],easi:[0,11,16,18,19],easier:[3,11,15],easili:4,eat:5,edit:20,effect:[2,3,5,8,15,19,20,24],effici:[7,14,19],efg:18,either:[1,2,3,5,11,13,18],elabor:18,eleg:[0,5,8,11,15,20],element:[2,3],elif:18,elimin:[5,18],elliott:[4,15],els:[2,3,5,13,15,18],else_:18,embed:[4,11,19],emit:18,empti:[3,5,8,16,18,23,24],encapsul:8,enclos:8,encod:7,encount:18,end:[5,6,11,13,16,18,23],endless:7,enforc:[2,8],engend:8,enough:[5,8,13,22,24],enstacken:[7,8,18],enter:[3,8,24],enter_guard:18,entir:23,entri:[3,19,22],enumer:18,epsilon:9,equal:[3,6,16,23],equat:[8,9],equival:15,ergo:[5,11],err:[11,17],error:[8,18,21],essai:0,establish:18,etc:[3,16,18,19,21],euler:20,euro:18,eval:[0,18],evalu:[1,2,3,8,9,11,12,13,14,15,16,18,22],event:15,eventu:[15,18],ever:18,everi:[1,7,15],everybodi:15,everyth:[3,5,11,12,15,18],evolv:10,examin:13,exampl:[0,3,5,6,18,20,21,23,24],exce:7,except:[5,8,11,17,18,21,24],execut:[0,1,2,3,8,13,14,15,16,18,19,23,24],exend:18,exercis:[5,11],exist:[4,11,18],expand:11,expect:[2,3,15,16,18,23,24],experi:[8,16],explain:18,explan:8,explor:[8,18],express:[0,1,2,3,4,11,13,14,18,19,20,22,23],expression_to_str:[18,23],extend:18,extra:[6,7],extract:[11,12,20],extrem:8,extrememli:8,f_g:18,f_in:18,f_out:18,f_python:18,facet:0,facil:8,fact:21,factor:[2,6,8,11,18],factori:[3,20],fail:[2,3,11,20,21,24],fail_fail:3,fairli:18,fake:5,fall:18,fals:[2,3,5,6,13,15,18,24],falsei:18,far:[9,11,13,18,24],fascin:0,favorit:15,fear:[11,18],few:[6,8,9,12,15,18],fewer:[3,8],fg_in:18,fg_out:18,fib:7,fib_gen:7,fibonacci:20,figur:[2,3,11,13,18],filter:11,fin:6,find:[2,3,5,6,7,15,16,18,20],finder:9,fine:[0,5,6,11,18,24],finite_state_machin:5,first:[3,5,7,8,9,11,12,13,14,16,19,20,24],first_two:[3,11,24],fit:[6,8],five:[6,8,20],fix:[2,3,5,13,18,24],fixm:[5,18],flag:[15,18],flatten:[8,16,18],flesh:5,flexibl:20,floatjoytyp:[18,24],floatstarjoytyp:18,floor:3,floordiv:[6,24],flow:8,follow:[0,2,3,5,8,10,13,15,16,18,19,24],foo:[8,10,11,15,18],foo_ii:10,fork:15,form:[2,3,4,5,6,7,13,16,18,23],forman:8,format:[17,18,20,22],formula:[0,6,20],forth:[8,18],forum:0,forward:18,found:8,four:[0,2,3,6,7,8,11,20],fourteen:6,fourth:[2,3,11,13,24],fractal:8,fraction0:8,fraction:[2,8],frame:13,framework:8,free:[4,8,11],freeli:2,from:[0,1,2,3,5,6,7,8,9,11,12,14,15,16,17,18,19,20,23],from_:5,front:[2,3,13],frozenset:5,fulin:15,full:6,fun:[5,20],func:18,functionjoytyp:[18,24],functionwrapp:3,functool:5,fundament:[0,20],funtion:11,further:[9,18,20],futur:15,g_in:18,g_out:18,garbag:8,gari:11,gcd:8,gener:[0,2,4,15,18,20,23,24],generated_librari:3,genrec:[3,8,11,13,15,16,18],geometr:6,get:[2,4,5,6,7,8,12,13,18,20],getch:5,getitem:3,getrecursionlimit:23,getsourc:8,ghc:4,give:[4,6,11,13,16,18,23],given:[2,3,6,7,9,11,15,18,19,20],global:[17,18],glue:8,goe:24,going:[5,11,12,15,16,18,19],good:[6,11,18],grab:18,grammar:21,grand:8,graph:15,graphic:5,graphviz:5,great:[0,8,18,20],greater:23,grind:18,group:0,grow:5,gsra:9,guard:[11,18,24],had:[5,6,19],haiku:8,half:[6,18,19],hallmark:15,hand:[5,8,14,18,20],handi:[9,18],handl:[11,18,23,24],happen:[8,18],happi:5,hard:[5,18,19],hardwar:4,has:[0,2,3,5,7,8,9,10,11,13,15,18,19,23],hasattr:18,hash:18,haskel:4,have:[2,3,5,6,7,8,9,10,13,14,15,18,19,20,23,24],haven:24,head:23,heh:18,help:[8,11,13,18],help_:3,helper:[3,5],herd:8,here:[5,6,7,11,16,18,19,24],hide:11,hierarchi:18,higher:[5,8,11,18],highli:8,hij:5,histori:[18,22,24],hit:5,hmm:[5,11],hoist:3,hold:[6,18],hood:11,hope:[0,6,8,20],hopefulli:13,host:20,how:[0,4,5,9,11,13,18,19,20],howev:[13,14,15,18],html:[2,3,7,12,13,20],http:11,huet:19,huge:11,hugh:[9,16],human:8,hybrid:24,hylomorph:20,hypothet:2,id_:3,idea:[4,6,8,18],ident:[3,5,13,18,24],if_not_empti:11,ift:[3,11,13,16,18,24],ignor:[1,3,11,18],iii:20,illustr:[5,13],imagin:[5,15,19],imap:18,imit:[5,16],immedi:[5,13],immut:[5,8,11],imper:13,implement:[0,1,2,3,4,8,10,11,13,14,15,20,24],implementaion:15,implicit:8,improv:18,includ:[4,11,15,16,18,24],inclus:6,incom:23,incompat:10,incorpor:12,increas:6,increment:[3,4,6,10,15],indetermin:24,index:[0,8,18,23],indexerror:23,indic:[15,16,18,24],ineffici:18,infer:[0,3,17],infer_:3,inferenc:24,info:[17,18],inform:[3,5,18,24],infra:[3,7,8,11,12,14,15,16,18,20,24],infrastructur:3,initi:[2,3,5,8,9,11,18],inlin:11,inner:18,inproceed:18,input:[1,9,15,17,18,24],input_:5,inscrib:3,inscribe_:3,insert:18,insight:13,inspect:8,inspect_stack:18,instal:0,instanc:18,instanti:[4,22],instead:[5,6,7,11,13,18,19,23,24],instruct:5,integ:[2,3,8,16,18,21],integr:3,intend:[0,8],interact:[8,20],interest:[0,6,11,18,20],interfer:15,interlud:20,intermedi:13,intern:[0,18,22,23],interpret:[0,4,10,14,21,22,24],interrupt:8,intersect:5,interspers:15,interv:[4,6],intjoytyp:[18,24],introduc:10,introduct:0,intstarjoytyp:18,intuit:18,invalid:24,invari:3,invent:18,involv:18,ipf:8,ipython:18,isinst:[5,18],isn:[5,11,19],issubclass:18,item:[2,3,8,11,13,15,16,18,20,23],iter:[1,3,5,8,13,15,16,18,20,23],iter_stack:[14,23],iteritem:[5,18],itertool:[5,18],its:[0,1,2,3,4,6,8,11,13,15,16,18,23],itself:[0,2,8,11,15,18,24],j05cmp:[2,3,13],jaanu:18,jmp:5,job:[15,20],john:[9,16],joi:[2,4,10,11,12,14,15,17],join:[5,18],joypi:19,joytypeerror:[17,24],jump:5,jump_from:5,junk:18,jupyt:20,just:[0,2,3,5,7,8,10,11,13,15,16,18,19,22],juxtaposit:15,keep:[5,11,12,15,18,19],kei:[5,16,20],kevin:0,key_n:11,keyerror:[5,11,18],kind:[2,4,8,11,13,16,18,24],kinda:18,kleen:[16,18,24],kleenestar:[18,24],kleffner:18,know:[6,11,18],knowledg:18,known:[4,15],kstar:5,l_kei:11,l_left:11,l_right:11,l_valu:11,label:[5,18],lambda:[4,5,18],languag:[3,4,5,8,10,11,14,18],larg:[5,18],larger:[20,23],largest:3,last:[6,11,13,18],lastli:7,later:[5,8,16,18],law:2,lazi:18,lazili:9,lcm:6,lead:[5,8,18,24],leaf:11,lean:8,learn:0,least:[2,6,13,18,23],least_fract:8,leav:[3,6,15],left:[5,8,12,13,15,16,18,19,22,23,24],leftov:13,legend:5,len:[5,18],length:[3,6,23],lens:13,less:[6,7,8,13,18,23],let:[7,9,11,12,13,16,18,19,20],letter:18,level:[4,5,11,17,18],librari:[0,5,14],like:[2,3,5,6,8,15,16,18,20,21,22,24],limit:[18,24],line:[3,8,11,12,18,22,24],linear:23,link:[0,5,18],linux:0,list:[0,3,5,6,8,9,11,15,16,18,19,22,24],list_to_stack:[18,23],liter:[1,11,16,18,19,21],literatur:18,littl:[5,7,11,15,18,20],live:20,lkei:16,load:[6,8],local:18,locat:2,locu:22,log:[17,18],log_2:11,logic:[0,6,20],longer:[11,18],look:[1,5,7,8,9,11,12,15,18],lookup:8,loop:[0,1,3,5,6,18,20,24],lose:18,lot:[5,8,11,18,19],love:6,low:[4,5],lower:6,lowercas:[5,18],lowest:11,lshift:24,machin:[0,20],machineri:[11,18],macro:8,made:[0,8,15,18,19],magic:18,mai:[2,13,15],mail:0,main:[0,3,8,12,15,18,19],mainloop:10,maintain:19,major:10,make:[2,3,4,6,8,11,13,14,15,16,18,19,20],make_gener:9,make_graph:5,manfr:[0,2,3,4,13],mani:[0,5,8,18],manipul:18,manner:12,map:[1,3,5,6,8,10,13,16,18,22],map_:3,marker:8,mask:[6,7],match:[0,1,18,20],materi:0,math:[0,8,9,11,12,18],mathemat:8,matter:[6,9,11,16],max_:3,maximum:3,mayb:[11,18],mean:[3,4,6,8,9,11,13,16,18,23,24],meant:[8,11,13,16],mem:5,member:[2,3,13],memo:5,mental:8,mention:2,mercuri:0,mess:18,messag:[17,18],meta:[8,11,14],meta_compos:[18,24],method:[0,3,8,18,20,22],midpoint:6,might:[4,5,7,11,18],mike:11,million:7,min_:3,mind:18,minimum:3,minor:11,minu:3,mirror:0,miscellan:0,mismatch:18,mix:[8,18],mod:3,mode:18,model:[4,8],modern:0,modif:[7,18],modifi:[8,11,19],modul:[0,1,3,8,18,21],modulo:18,modulu:[8,24],moment:18,month:8,more:[0,3,4,5,6,7,8,9,13,14,15,16,18,21,23,24],most:[5,18,24],mostli:0,move:[5,11],movement:2,much:[5,6,7,11,13,18],muck:11,mul:[3,8,12,17,19,22,24],multi:3,multipl:[20,24],multipli:3,must:[2,3,6,10,13,15,16,18,21],myself:18,n10001:18,n10002:18,n10003:18,n1001:18,n1002:18,n1003:18,name:[1,3,5,8,10,11,13,18,19,20,21,22,23,24],narr:18,natur:[5,6,7,11,18],navig:19,nearli:18,neat:11,neato:18,necessarili:18,need:[2,3,6,7,9,10,11,13,15,18],neg:[3,12,24],neither:[15,18],ness:5,nest:[3,8,11,19],network:8,never:[5,10,13],new_def:18,new_f:18,new_fo:18,new_kei:11,new_valu:11,newton:[0,20],next:[5,6,15,16,18,24],nice:[0,5,13,23],niether:2,node:[5,16,20],node_kei:11,node_valu:11,non:[5,16,18,24],none:[1,3,18,24],nope:16,nor:5,normal:15,notat:[8,11],note:[2,5,6,9,11,13,15,18,23],notebook:[6,7,8,18,19,20],notebook_preambl:[2,6,7,9,11,12,13,14,16,18,19],noth:[2,11,15],notic:6,now:[3,5,6,7,8,13,14,16,18,20],nth:[3,23],nullari:[8,11,15,18,24],number:[1,2,3,6,7,9,15,23,24],numberjoytyp:[18,24],numberstarjoytyp:18,numer:18,object:[5,18,21],observ:6,obviou:7,obvious:18,occur:11,odd:[6,7],off:[2,3,6,7,12,18,19],often:[5,15],old:[2,14],old_k:11,old_kei:11,old_valu:11,omg:5,omit:[13,18,21],onc:[3,5,10,11],one:[2,3,5,6,7,11,13,15,16,18,22,23,24],ones:[5,7,18],onli:[2,3,5,6,11,13,15,18,19,23,24],onto:[1,2,3,8,13,23],open:[8,18],oper:[0,3,5,8,11,13,20,23],oppos:18,optim:11,option:[1,8,11,18,23],orchestr:15,order:[0,2,3,8,13,15,17,18,20,23],org:[0,11],origin:[0,1,2,3,11,19],other:[0,2,3,4,5,8,11,13,16,18,23,24],otherwis:[3,5,6,7,11,16,18,24],our:[5,6,7,8,9,13,16,18],out:[2,3,4,6,7,8,9,11,12,13,15,18,19,20],outcom:16,outlin:5,output:[5,9,13,15,17,18,24],outsid:4,over:[3,4,6,7,8,9,11,12,15,16,18,20,24],overhaul:18,overview:[3,18],own:[11,18],pack:23,packag:[0,8],page:[0,11,18,23],pair:[2,3,6,7,11,18],palidrom:6,palindrom:6,pam:8,paper:[4,8,13,15,19],paradigm:20,parallel:[2,20],paramet:[1,2,3,13,14,21,22,23],parameter:20,paramorph:13,parenthes:[11,23],pariti:7,pars:[0,3,5,8],parse_definit:3,parseerror:21,parser:[0,17,18],part:[2,3,9,13,16,20],partial:[5,18],particular:19,pass:[0,5,11,18,22,24],patch:5,path:[5,18,20],pattern:[5,6,15,16,20],pe1:[6,7],pe2:7,pearl:19,pend:[3,8,13,18,19,22],peopl:20,per:[8,16],perfectli:15,perform:[5,15,18],perhap:7,period:8,permit:[15,18,23],permut:18,persist:[3,11],phase:2,phi:5,pick:[6,7,15,23],pickl:8,pictur:11,piec:13,pip:0,place:[3,6,8,18],plai:0,plu:3,plug:[7,13,16],point:[4,5,8,11,13,15],pointless:2,poly_compos:24,pool:15,pop:[3,5,6,7,8,11,13,14,16,17,23,24],popd:[3,8,9,11,14,15,18,24],popdd:[3,7,12,18,24],popop:[3,6,7,8,9,11,16,18,24],popopd:[3,24],popopdd:[3,24],posit:[3,6,8,13],possibilit:11,possibl:[11,16,18,20],post:8,poswrd:18,potenti:15,pow:24,power:[8,18],pprint:5,pragmat:6,preambl:9,preceed:15,precis:[0,1],pred:[3,18,24],predecessor:3,predic:[2,3,5,7,13,15,24],prefix:[18,22],preliminari:5,present:18,preserv:[4,16],pretti:[9,11,12,15,16,18,22,23],pretty_print:0,previou:[8,15],prime:9,primit:[2,3,18,20],primrec:[3,7,8,9,13],print:[0,1,2,3,5,17,18,22,23,24],probabl:[7,8,11,18],problem:[8,18,20],proc_curr:11,proc_left:11,proc_right:11,proce:[6,24],process:[5,8,16,18,22],produc:[3,6,11,13,16,18],product:[5,7,8,17,18],program:[0,2,3,7,8,9,11,13,15,18,19,24],programm:[15,18],progress:15,project:20,prolog:18,promis:15,prompt:8,proper:[2,3,13,15,24],properti:0,provid:[0,3,4,8,15,18,24],pun:[0,8],punctuat:18,pure:[0,5],puriti:8,purpos:8,push:[2,3,8,13,19,23],put:[1,2,7,8,15,18,20,23],pypi:0,python3:8,python:[0,2,3,5,11,13,15,19,20,21,23,24],quadrat:[0,20],queri:[11,16],query_kei:16,queu:13,quit:[0,16],quot:[0,3,7,8,11,12,13,15,16,18,19,22,24],quotat:[2,3,13],quotient:3,r_kei:11,r_left:11,r_right:11,r_valu:11,rais:[5,11,18,21,23],rang:[5,8,18],range_revers:13,range_to_zero:8,ranger:13,ranger_revers:13,rankdir:5,raphson:9,rather:[6,8,13,16],ratio:8,reach:[5,6,7,13],read:[0,1,6,7,11,18,19],readabl:14,reader:[5,11],readi:18,real:11,realiz:[4,11],rearrang:[2,3,11,18],reason:[6,8,15,18],rebuild:[16,19],rec1:[2,3,13],rec2:[2,3,13],recent:18,recogn:21,recombin:15,record:[8,22],recur:[3,13,18],recurs:[0,2,3,5,7,8,9,15,18,20,23],recus:8,redefin:20,redistribut:[3,8],redo:5,reduc:[2,18],redund:23,refactor:[8,10],refer:[0,2],referenti:15,reflect:15,regard:15,regist:2,regular:[18,20,21],reifi:[17,24],reimplement:[15,20],relabel:24,relat:[5,18],releas:10,remain:[2,8,10,18],remaind:[3,9],rememb:5,remind:18,remov:[3,11,18,23],render:20,repeat:6,repeatedli:6,repetit:5,repl:[0,1],replac:[0,2,3,7,12,13,15,16,18,19,20,23],repositori:0,repr:[5,18],repres:[2,8,11,15,21,22,24],represent:[23,24],reprod:7,repurpos:18,requir:[15,18,23],res:18,research:18,resembl:8,resolut:15,resourc:[3,15],respect:[5,6,15],rest:[3,6,7,8,11,13,19,20,23,24],rest_two:11,restart:3,restor:2,result:[1,2,3,5,6,11,12,13,15,16,18,19],resum:8,retir:2,retri:8,reus:[11,18],revers:[3,6,7,13,18,19,20,23],revisit:18,rewrit:[3,8,18],rewritten:8,rid:11,right:[7,8,12,16,18,20,22,23,24],rightest:11,rightmost:6,rigor:15,risk:18,rkei:16,rob:18,roll:[3,9,11,16],roll_dn:18,rolldown:[3,17,18,24],rollup:[3,18,24],root:[3,9,12],round:18,row:5,rrest:[3,17,18,24],rshift:24,rule:[15,20],run:[0,1,3,6,8,9,11,12,13,15,16,18,19],runtim:15,runtimeerror:23,sai:[5,7,11,12,16,18],same:[2,4,6,11,15,18,23],sandwich:[2,3,13],save:[2,5,6,8],scan:3,scanner:[8,21],scenario:19,scope:[7,11],search:[0,11],sec:[18,24],second:[3,8,11,13,16,23,24],section:13,see:[0,5,7,8,9,10,12,13,14,18,19,22],seem:[0,6,8,16,18,24],seen:[18,19,24],select:3,self:[5,15,18],semant:[2,3,8,10,11,15,18],semi:8,send:8,sens:[0,2,6,18,19],separ:[8,15,18,21],seq:18,sequenc:[0,1,2,3,6,8,11,13,14,19,20,21,24],sequence_to_stack:18,seri:[6,7,11,19],ses:18,set:[2,3,5,13,18,20],seven:[6,7],sever:[0,4,8,13],shape:[5,15],share:[3,8],shelf:2,shew:5,shift:[6,7],shorter:20,shorthand:11,should:[2,3,5,6,11,13,15,18],shouldn:8,show:[4,15,18,19],shunt:[3,19],side:[5,11,17,18,24],sign:3,signatur:24,signifi:[8,11],similar:[11,16,18],simon:8,simpl:[5,8,13,23,24],simplefunctionwrapp:[3,14,18],simpler:16,simplest:[18,20],simpli:4,simplifi:[6,11,19],sinc:[2,6,11,18],singl:[3,7,8,14,15,18,21,24],singleton:5,situ:11,situat:11,six:[6,7,8],sixti:[6,7],size:[5,8,20],skeptic:8,skip:18,slight:9,slightli:[11,13,18],smallest:3,smart:11,softwar:8,solei:2,solut:[6,7],solvabl:8,some:[2,3,5,7,8,11,13,15,16,18,20,23,24],somehow:[11,18],someth:[2,10,11,18],sometim:11,somewher:[11,20],sort:[3,5,11,15,18],sort_:3,sourc:[0,1,3,18,20,21,22,23,24],space:[6,22],span:6,spawn:18,special:[7,11,20],specif:[0,4],specifi:[11,15,24],speed:14,spell:[5,16],sphinx:[20,23],spirit:[0,1,16],split:[5,18,24],sqr:[3,8,9,12,19],sqrt:[3,9,18,24],squar:[3,9,18,21],stack:[0,1,3,6,7,9,11,12,13,14,15,16,17,19,20,21,22,24],stack_effect:18,stack_effect_com:18,stack_to_str:[17,23],stacki:18,stackjoytyp:[18,24],stackstarjoytyp:18,stage:16,stai:[0,1],stand:[4,5],standard:[8,11],star:[16,18,24],stare:11,start:[5,6,7,8,9,11,13,16,18,24],state:[8,20],state_nam:5,statement:[3,5],stdout:[17,18],step:[3,6,8,11,14,18,19,20],still:[5,11,18],stop:11,stopiter:5,storag:[6,11],store:[6,13,18],stori:13,str:[1,5,18,21,22,23],straightforward:[5,7,9,18,20],stream:[6,17,18],stretch:11,string:[1,2,3,8,18,19,20,21,22,23,24],stringi:5,structur:[8,15,16,18,19,20,23],stuck:5,studi:5,stuff:[11,18],stuncon:[3,24],stununcon:[3,24],style:[0,4,18],sub:[10,15,24],subclass:8,subject:[15,19],subsequ:15,subset:[18,24],substitut:[5,11,18,24],subtract:6,subtyp:20,succ:[3,18,24],succe:18,success:9,suck:18,suffic:18,suffici:11,suffix:18,suggest:[4,5,11],suitabl:[3,4,6],sum:[3,7,8,12,13,14,16],sum_:[3,18],summand:6,sumtre:16,suppli:[11,21],support:[8,18,22,23],sure:15,suspect:2,svg:5,swaack:[3,12,14,18,19,24],swap:[3,6,7,8,9,11,13,14,15,16,17,19,24],swon:[3,7,8,13,16,18,19,24],swoncat:[7,8,9,13,16],swuncon:13,sym:5,symbol:[1,2,3,5,15,18,19,20,21],symboljoytyp:[18,24],symmetr:[6,11],symmetri:5,syntact:8,syntax:[8,23],sys:[17,18,23],system:[8,11,15],tabl:[5,18],tag:[5,18],tail:[11,18,20,23],tailrec:3,take:[3,5,6,8,9,11,13,15,18,23],talk:[8,11,18,23],target:19,tast:4,tbd:8,tear:13,technic:2,techniqu:[4,19],technolog:2,temporari:19,ten:6,term:[1,2,5,8,9,13,15,18,20,21,23,24],termin:[2,3,5,13],ternari:8,test:[2,3,13],text:[0,1,3,18],text_to_express:[8,17,21],textjoytyp:24,textual:8,than:[0,3,5,6,7,8,9,13,15,16,18,23,24],thei:[2,3,5,6,7,8,11,13,15,18,19,21,23,24],them:[2,3,5,6,7,11,13,15,18,19,20,24],themselv:[15,18,24],theori:[2,3,13,15],therefor:7,thi:[0,1,2,3,4,5,6,7,8,9,12,13,15,16,18,19,20,21,22,23,24],thing:[2,7,11,13,15,18,19,21,23,24],think:[2,6,8,11,13,15,16,18],third:[3,7,8,11,24],thirti:6,those:[2,3,5,11,13,18,20,24],though:[6,15],thought:[8,15],thousand:6,thread:[2,15],three:[2,3,5,6,8,11,12,16,18,20],through:[1,6,8,16,18,19,23,24],thun:[2,3,4,10,13,15],thunder:8,thunk:15,time:[3,5,6,8,9,11,13,15,18,19],titl:18,to_check:5,to_set:11,todai:8,todo:[8,21],togeth:[7,8,15,18,20],token:21,toler:20,too:[5,13,18],tool:[8,18],tooo:18,top:[2,3,8,13,18,22,23],total:6,tower:18,trace:[0,8,12,13,19,20,23],traceback:18,traceprint:22,track:[12,18,19],tracker:0,transform:4,transit:5,translat:[4,12,18],trap:5,travers:[0,20],treasur:0,treat:[0,2,3,13,18,20],treatment:7,tree:[0,8,20],treegrind:20,treestep:[0,20],tri:6,triangl:15,triangular_numb:13,trick:[6,18],tricki:18,trinari:24,trobe:0,trove:0,truediv:24,truthi:[3,8,15,18],tuck:[3,8,18,24],tupl:[3,5,8,18,23,24],turn:[2,3,5,18,24],twice:[11,13],two:[2,3,6,8,9,11,12,13,15,16,17,18,19,20,23,24],txt:3,type:[0,1,4,8,11,13,15,20,21,22,23],type_check:24,typeerror:18,typeless:18,typic:[2,3,12,13],unari:8,unarybuiltinwrapp:3,unbalanc:[11,21],unbound:24,unchang:11,uncompil:18,uncon:[3,7,8,11,13,16,19,24],under:[2,3,8,11],underli:[5,15,18],underscor:18,understand:[0,11],undistinguish:11,undocu:8,unfinish:5,unfortun:23,uni_unifi:24,unicod:18,unif:[18,20],unifi:[17,24],union:5,uniqu:[3,5,11,18],unit:[3,8,13,15,24],univers:[0,8,15,18,24],unlik:15,unnecessari:20,unnecesssari:18,unpack:[2,3,11,23],unpair:6,unquot:[8,16,21],unrol:5,unstack:18,unswon:[3,24],untangl:13,until:[5,7,15],unus:6,unusu:11,unwrap:5,updat:[0,17,20,24],uppercas:5,upward:15,usag:8,use:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,19,20,23],used:[3,4,8,11,13,15,18,19,21,23,24],useful:[0,15,18],user:16,uses:[2,3,5,6,13],using:[7,11,12,13,16,19,24],usual:[0,2,13],util:[0,3,14,17,18],valid:18,valu:[0,1,2,3,6,8,9,12,13,14,15,16,18,20,21,23,24],value_n:11,valueerror:[5,18,23],variabl:[18,20,24],variant:11,variat:[13,15,20],varieti:[4,8],variou:0,vener:23,verbos:4,veri:[0,1,4,5,8,11,23],versa:[2,18],version:[0,1,2,5,7,10,16,19,20],via:8,vice:[2,18],view:[11,20],viewer:[1,8,10,22],vii:20,visibl:18,von:[0,2,3,4,13],waaaai:5,wai:[0,2,3,4,5,6,8,13,14,15,18],wait:15,want:[2,3,6,7,9,11,13,18],warranti:[3,8],wash:8,wast:8,web:23,websit:[0,6],welcom:8,well:[0,4,8,9,11,18,21],went:18,were:[8,18,19],what:[2,3,4,5,8,11,13,15,16,18,22],whatev:[2,3,13,16,23],when:[6,7,8,11,13,15,18,19,21,23,24],where:[2,3,5,8,11,13,18,20,23],whether:[3,13],which:[0,1,3,5,6,8,9,11,15,16,18,19,21,23,24],whole:[2,3,6,13,16,18],whose:7,why:[9,15,16],wiki:11,wikipedia:[0,11,19],wildli:8,wind:8,wire:13,within:[8,11,14,20],without:[2,8,11,12,15,18],won:[11,18,23],word:[0,3,6,8,13,19],work:[0,3,5,6,7,8,9,11,12,13,15,16,19,20,23,24],worker:15,worri:15,worth:6,would:[2,6,7,8,9,11,13,15,18,19,23,24],wrap:[3,8],wrapper:18,write:[4,5,9,11,13,15,16,18,19,20,23],written:[0,1,9,11,14,18,23],wrong:2,wrote:18,xrang:18,yang:18,yeah:15,year:[8,18],yet:[11,15,18,19,24],yield:[2,3,13,18,23,24],yin:[3,20],yin_funct:3,you:[0,2,3,5,6,7,8,10,11,12,13,14,15,16,18,19,22,23],your:[2,3,8,13,18],yourself:[5,8,11],zero:[3,5,11,13,15,16,18,21,23,24],zerodivisionerror:18,zip:[5,6,18],zip_:3,zipper:[0,20],zstr:19},titles:["Thun 0.3.0 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","\u2202RE","Developing a Program in Joy","Using <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Recursion Combinators","Replacing Functions in the Dictionary","The Four Fundamental Operations of Definite Action","Treating Trees II: <code class=\"docutils literal notranslate\"><span class=\"pre\">treestep</span></code>","Type Checking","The Blissful Elegance of Typing Joy","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026","Type Inference of Joy Expressions"],titleterms:{"\u03bb":5,"\u03d5":5,"case":[9,11],"function":[2,3,5,8,9,11,13,14,15,16,18],"long":14,"new":11,"p\u00f6ial":18,"try":5,"void":2,"while":[2,15],Adding:11,One:[7,11],The:[6,8,11,13,15,16,18],There:8,Using:7,With:[5,16],about:20,action:15,add:[2,11],adding:11,address:19,alphabet:5,altern:16,ana:13,analysi:6,anamorph:[2,13],app1:2,app2:2,app3:2,appendix:[11,13,18],appli:15,approxim:9,argument:18,auto:3,averag:2,base:[9,11],binari:[2,11,16],bliss:18,both:11,branch:[2,11,15],brzozowski:5,can:11,cata:13,catamorph:13,categor:4,chatter:2,check:17,child:11,choic:2,clear:2,cleav:[2,15],cmp:11,code:[8,11],combin:[2,11,13,18],comment:18,compact:5,compar:11,comparison:2,compil:[7,18],compile_:18,compos:18,comput:9,con:[2,18],concat:2,conclus:[13,18],consecut:9,continu:8,current:11,datastructur:[5,8,11,19],deal:18,defin:[11,16],definit:[12,15],delabel:18,delet:11,deriv:[5,12,13,16],design:13,determin:19,develop:6,diagram:5,dialect:0,dictionari:14,dip:[2,19],dipd:2,dipdd:2,direco:7,disenstacken:2,distinguish:18,div:2,doc_from_stack_effect:18,document:0,doe:11,down_to_zero:2,drive:5,drop:2,dup:[2,18],dupd:2,dupdip:2,effect:18,eleg:18,els:11,empti:11,enstacken:2,equal:11,essai:20,euler:[6,7],eval:8,even:7,exampl:[2,8,11,13,16,17],execut:22,explor:5,express:[5,8,21,24],extract:16,factori:13,fail:17,fibonacci:7,filter:6,find:[9,11,13],finish:15,finit:5,first:[2,6,15,18],five:7,flatten:2,flexibl:16,floordiv:2,formula:12,found:11,four:[13,15],from:13,fsm:5,fulmin:15,fun:13,fundament:15,further:6,gcd:2,gener:[3,5,6,7,9,13],genrec:2,get:[11,16],getitem:2,given:[13,16],greater:11,group:2,handl:15,have:[11,16],help:2,highest:11,host:0,how:[6,7],hybrid:18,hylo:13,hylomorph:13,identifi:18,ift:[2,15],iii:18,implement:[5,18],indic:0,infer:[18,24],inferenc:18,inform:0,infra:[2,19],integ:[6,13],interest:7,interlud:11,intern:21,interpret:[1,8,18],item:19,iter:[6,11],joi:[0,1,3,6,8,13,18,19,20,21,22,23,24],join:15,just:6,kei:11,kind:15,languag:0,larger:5,least_fract:2,left:11,less:11,let:[5,6],letter:5,librari:[3,8,18],like:11,list:[2,13,23],literari:8,littl:6,logic:[2,18],loop:[2,8,15],lower:11,lshift:2,machin:5,make:[7,9],mani:6,map:[2,15],match:5,math:2,memoiz:5,method:9,min:2,miscellan:2,mod:2,modifi:18,modulu:2,more:11,most:11,mul:[2,18],multipl:[6,7,18],must:11,name:12,neg:2,newton:9,next:9,node:11,non:11,now:11,nullari:2,nulli:5,number:[13,18],one:8,onli:8,oper:15,order:[11,16],osdn:0,other:15,our:11,out:5,over:2,pack:6,pam:[2,15],para:13,paradigm:18,parallel:15,parameter:[11,16],pars:[2,21],parser:[8,21],part:18,pass:8,path:19,pattern:13,per:11,pop:[2,18],popd:2,popop:2,pow:2,power:7,pred:2,predic:[6,9,11,16],pretty_print:22,primit:13,primrec:2,print:8,problem:[6,7],process:11,product:2,program:[4,6,12,16,20],progress:18,project:[0,6,7],pure:8,put:[11,12,16],python:[8,14,18],quadrat:12,quick:0,quot:[2,23],rang:[2,6,13],range_to_zero:2,read:8,recur:[9,11],recurs:[11,13,16],redefin:[11,16],refactor:[6,11],refer:3,regular:[5,8],reimplement:16,relabel:18,rem:2,remaind:2,remov:2,render:6,repl:8,replac:[11,14],repres:[5,18],represent:5,reset:7,rest:[2,18],revers:[2,5,17],right:[11,19],rightmost:11,roll:[2,18],rolldown:2,rollup:2,rshift:2,rule:[5,18],run:[2,7],second:[2,18],select:2,sequenc:[7,15,18,23],set:[9,11],shorter:14,should:8,shunt:2,simpl:18,simplest:6,size:[2,14],sourc:11,special:[13,18],sqr:[2,18],sqrt:[2,12],stack:[2,8,18,23],start:0,state:5,step:[2,13,16],straightforward:12,stream:5,string:5,structur:11,style:8,sub:[2,11],subtyp:18,succ:2,sum:[2,6],swaack:2,swap:[2,18],swon:2,swoncat:2,symbol:[8,13],tabl:0,tail:13,take:2,term:[6,7,16],ternari:2,text:21,than:11,them:12,thi:11,third:[2,18],three:7,thun:[0,8],time:[2,7],togeth:[11,12,16],token:8,toler:9,trace:[14,22],traceprint:8,trampolin:5,travers:[11,16,19],treat:[11,16],tree:[11,16,19],treegrind:16,treestep:16,triangular:13,truediv:2,truthi:2,tuck:2,two:[5,7],type:[17,18,24],unari:2,unbound:18,uncon:[2,18],unif:17,unifi:18,unit:2,unnecessari:6,unquot:2,unstack:2,updat:[10,18],use:18,util:[22,23,24],valu:[7,11],variabl:12,variat:7,version:[6,11,14,18],view:8,vii:18,which:13,within:9,word:2,work:[17,18],write:12,xor:2,yin:18,zero:7,zip:2,zipper:19}})
\ No newline at end of file
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Stack or Quote or Sequence or List… — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Parsing Text into Joy Expressions" href="parser.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="stack-or-quote-or-sequence-or-list">
values from (at least) one end.</p>
<p>There is no “Stack” Python class, instead we use the <a class="reference external" href="https://en.wikipedia.org/wiki/Cons#Lists">cons list</a>, a
venerable two-tuple recursive sequence datastructure, where the
-empty tuple <code class="docutils literal notranslate"><span class="pre">()</span></code> is the empty stack and <code class="docutils literal notranslate"><span class="pre">(head,</span> <span class="pre">rest)</span></code> gives the recursive
-form of a stack with one or more items on it:</p>
-<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stack</span> <span class="o">:=</span> <span class="p">()</span> <span class="o">|</span> <span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
+empty tuple <code class="docutils literal notranslate"><span class="pre">()</span></code> is the empty stack and <code class="docutils literal notranslate"><span class="pre">(head,</span> <span class="pre">rest)</span></code> gives the
+recursive form of a stack with one or more items on it:</p>
+<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">stack</span> <span class="p">:</span><span class="o">=</span> <span class="p">()</span> <span class="o">|</span> <span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="n">stack</span><span class="p">)</span>
</pre></div>
</div>
<p>Putting some numbers onto a stack:</p>
one-by-one in order. There are also two functions to generate string representations
of stacks. They only differ in that one prints the terms in stack from left-to-right while the other prints from right-to-left. In both functions <em>internal stacks</em> are
printed left-to-right. These functions are written to support <a class="reference internal" href="pretty.html"><span class="doc">Tracing Joy Execution</span></a>.</p>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.stack.concat">
-<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">concat</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">quote</span></em>, <em class="sig-param"><span class="n">expression</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#concat"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.concat" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.stack.</code><code class="descname">concat</code><span class="sig-paren">(</span><em>quote</em>, <em>expression</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#concat"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.concat" title="Permalink to this definition">¶</a></dt>
<dd><p>Concatinate quote onto expression.</p>
<p>In joy [1 2] [3 4] would become [1 2 3 4].</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><ul class="simple">
-<li><p><strong>quote</strong> (<em>stack</em>) – A stack.</p></li>
-<li><p><strong>expression</strong> (<em>stack</em>) – A stack.</p></li>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>quote</strong> (<em>stack</em>) – A stack.</li>
+<li><strong>expression</strong> (<em>stack</em>) – A stack.</li>
</ul>
-</dd>
-<dt class="field-even">Raises</dt>
-<dd class="field-even"><p><strong>RuntimeError</strong> – if quote is larger than sys.getrecursionlimit().</p>
-</dd>
-<dt class="field-odd">Return type</dt>
-<dd class="field-odd"><p>stack</p>
-</dd>
-</dl>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Raises:</th><td class="field-body"><p class="first"><strong>RuntimeError</strong> – if quote is larger than sys.getrecursionlimit().</p>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">stack</p>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.stack.expression_to_string">
-<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">expression_to_string</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">expression</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#expression_to_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.expression_to_string" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.stack.</code><code class="descname">expression_to_string</code><span class="sig-paren">(</span><em>expression</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#expression_to_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.expression_to_string" title="Permalink to this definition">¶</a></dt>
<dd><p>Return a “pretty print” string for a expression.</p>
<p>The items are written left-to-right:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">top</span><span class="p">,</span> <span class="p">(</span><span class="n">second</span><span class="p">,</span> <span class="o">...</span><span class="p">))</span> <span class="o">-></span> <span class="s1">'top second ...'</span>
</pre></div>
</div>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><p><strong>expression</strong> (<em>stack</em>) – A stack.</p>
-</dd>
-<dt class="field-even">Return type</dt>
-<dd class="field-even"><p>str</p>
-</dd>
-</dl>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>expression</strong> (<em>stack</em>) – A stack.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">str</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.stack.iter_stack">
-<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">iter_stack</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#iter_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.iter_stack" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.stack.</code><code class="descname">iter_stack</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#iter_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.iter_stack" title="Permalink to this definition">¶</a></dt>
<dd><p>Iterate through the items on the stack.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><p><strong>stack</strong> (<em>stack</em>) – A stack.</p>
-</dd>
-<dt class="field-even">Return type</dt>
-<dd class="field-even"><p>iterator</p>
-</dd>
-</dl>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>stack</strong> (<em>stack</em>) – A stack.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">iterator</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.stack.list_to_stack">
-<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">list_to_stack</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">el</span></em>, <em class="sig-param"><span class="n">stack</span><span class="o">=</span><span class="default_value">()</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#list_to_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.list_to_stack" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.stack.</code><code class="descname">list_to_stack</code><span class="sig-paren">(</span><em>el</em>, <em>stack=()</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#list_to_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.list_to_stack" title="Permalink to this definition">¶</a></dt>
<dd><p>Convert a Python list (or other sequence) to a Joy stack:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span> <span class="o">-></span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">())))</span>
</pre></div>
</div>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><ul class="simple">
-<li><p><strong>el</strong> (<em>list</em>) – A Python list or other sequence (iterators and generators
-won’t work because <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> is called on <code class="docutils literal notranslate"><span class="pre">el</span></code>.)</p></li>
-<li><p><strong>stack</strong> (<em>stack</em>) – A stack, optional, defaults to the empty stack.</p></li>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>el</strong> (<em>list</em>) – A Python list or other sequence (iterators and generators
+won’t work because <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> is called on <code class="docutils literal notranslate"><span class="pre">el</span></code>.)</li>
+<li><strong>stack</strong> (<em>stack</em>) – A stack, optional, defaults to the empty stack.</li>
</ul>
-</dd>
-<dt class="field-even">Return type</dt>
-<dd class="field-even"><p>stack</p>
-</dd>
-</dl>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">stack</p>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.stack.pick">
-<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">pick</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">n</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#pick"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.pick" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.stack.</code><code class="descname">pick</code><span class="sig-paren">(</span><em>stack</em>, <em>n</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#pick"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.pick" title="Permalink to this definition">¶</a></dt>
<dd><p>Return the nth item on the stack.</p>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><ul class="simple">
-<li><p><strong>stack</strong> (<em>stack</em>) – A stack.</p></li>
-<li><p><strong>n</strong> (<em>int</em>) – An index into the stack.</p></li>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
+<li><strong>stack</strong> (<em>stack</em>) – A stack.</li>
+<li><strong>n</strong> (<em>int</em>) – An index into the stack.</li>
</ul>
-</dd>
-<dt class="field-even">Raises</dt>
-<dd class="field-even"><ul class="simple">
-<li><p><strong>ValueError</strong> – if <code class="docutils literal notranslate"><span class="pre">n</span></code> is less than zero.</p></li>
-<li><p><strong>IndexError</strong> – if <code class="docutils literal notranslate"><span class="pre">n</span></code> is equal to or greater than the length of <code class="docutils literal notranslate"><span class="pre">stack</span></code>.</p></li>
+</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Raises:</th><td class="field-body"><ul class="first simple">
+<li><strong>ValueError</strong> – if <code class="docutils literal notranslate"><span class="pre">n</span></code> is less than zero.</li>
+<li><strong>IndexError</strong> – if <code class="docutils literal notranslate"><span class="pre">n</span></code> is equal to or greater than the length of <code class="docutils literal notranslate"><span class="pre">stack</span></code>.</li>
</ul>
-</dd>
-<dt class="field-odd">Return type</dt>
-<dd class="field-odd"><p>whatever</p>
-</dd>
-</dl>
+</td>
+</tr>
+<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">whatever</p>
+</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.stack.stack_to_string">
-<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">stack_to_string</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#stack_to_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.stack_to_string" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.stack.</code><code class="descname">stack_to_string</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#stack_to_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.stack_to_string" title="Permalink to this definition">¶</a></dt>
<dd><p>Return a “pretty print” string for a stack.</p>
<p>The items are written right-to-left:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">top</span><span class="p">,</span> <span class="p">(</span><span class="n">second</span><span class="p">,</span> <span class="o">...</span><span class="p">))</span> <span class="o">-></span> <span class="s1">'... second top'</span>
</pre></div>
</div>
-<dl class="field-list simple">
-<dt class="field-odd">Parameters</dt>
-<dd class="field-odd"><p><strong>stack</strong> (<em>stack</em>) – A stack.</p>
-</dd>
-<dt class="field-even">Return type</dt>
-<dd class="field-even"><p>str</p>
-</dd>
-</dl>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>stack</strong> (<em>stack</em>) – A stack.</td>
+</tr>
+<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">str</td>
+</tr>
+</tbody>
+</table>
</dd></dl>
</div>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Stack or Quote or Sequence or List…</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#module-joy.utils.stack"><code class="docutils literal notranslate"><span class="pre">joy.utils.stack</span></code></a></li>
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Stack or Quote or Sequence or List…</a><ul>
+<li><a class="reference internal" href="#module-joy.utils.stack"><code class="docutils literal notranslate"><span class="pre">joy.utils.stack</span></code></a></li>
</ul>
</li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1"><a class="reference internal" href="types.html">Type Inference of Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="_sources/stack.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
-<!DOCTYPE html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
+<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Type Inference of Joy Expressions — Thun 0.3.0 documentation</title>
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
- <script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
- <script src="_static/jquery.js"></script>
- <script src="_static/underscore.js"></script>
- <script src="_static/doctools.js"></script>
- <script src="_static/language_data.js"></script>
- <script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="_static/documentation_options.js"></script>
+ <script type="text/javascript" src="_static/jquery.js"></script>
+ <script type="text/javascript" src="_static/underscore.js"></script>
+ <script type="text/javascript" src="_static/doctools.js"></script>
+ <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Essays about Programming in Joy" href="notebooks/index.html" />
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
-
-
<div class="body" role="main">
<div class="section" id="type-inference-of-joy-expressions">
<span class="n">unswons</span> <span class="o">=</span> <span class="p">([</span><span class="n">a1</span> <span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="o">--</span> <span class="p">[</span><span class="o">...</span><span class="mi">1</span><span class="p">]</span> <span class="n">a1</span><span class="p">)</span> <span class="o">*</span>
</pre></div>
</div>
-<span class="target" id="module-joy.utils.types"></span><dl class="py class">
+<span class="target" id="module-joy.utils.types"></span><dl class="class">
<dt id="joy.utils.types.AnyJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">AnyJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#AnyJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.AnyJoyType" title="Permalink to this definition">¶</a></dt>
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">AnyJoyType</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#AnyJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.AnyJoyType" title="Permalink to this definition">¶</a></dt>
<dd><p>Joy type variable. Represents any Joy value.</p>
</dd></dl>
-<dl class="py class">
-<dt id="joy.utils.types.AnyStarJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">AnyStarJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#AnyStarJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.AnyStarJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
-<dt id="joy.utils.types.AnyStarJoyType.kind">
-<code class="sig-name descname">kind</code><a class="headerlink" href="#joy.utils.types.AnyStarJoyType.kind" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <a class="reference internal" href="#joy.utils.types.AnyJoyType" title="joy.utils.types.AnyJoyType"><code class="xref py py-class docutils literal notranslate"><span class="pre">AnyJoyType</span></code></a></p>
-</dd></dl>
-
-</dd></dl>
-
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.BooleanJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">BooleanJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#BooleanJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.BooleanJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">BooleanJoyType</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#BooleanJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.BooleanJoyType" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="attribute">
<dt id="joy.utils.types.BooleanJoyType.accept">
-<code class="sig-name descname">accept</code><a class="headerlink" href="#joy.utils.types.BooleanJoyType.accept" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">builtins.bool</span></code></p>
+<code class="descname">accept</code><a class="headerlink" href="#joy.utils.types.BooleanJoyType.accept" title="Permalink to this definition">¶</a></dt>
+<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">__builtin__.bool</span></code></p>
</dd></dl>
</dd></dl>
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.CombinatorJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">CombinatorJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">sec</span></em>, <em class="sig-param"><span class="n">number</span></em>, <em class="sig-param"><span class="n">expect</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#CombinatorJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.CombinatorJoyType" title="Permalink to this definition">¶</a></dt>
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">CombinatorJoyType</code><span class="sig-paren">(</span><em>name</em>, <em>sec</em>, <em>number</em>, <em>expect=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#CombinatorJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.CombinatorJoyType" title="Permalink to this definition">¶</a></dt>
<dd><p>Represent combinators.</p>
<p>These type variables carry Joy functions that implement the
behaviour of Joy combinators and they can appear in expressions.
guard against being used on invalid types.</p>
</dd></dl>
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.FloatJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">FloatJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#FloatJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.FloatJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">FloatJoyType</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#FloatJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.FloatJoyType" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="attribute">
<dt id="joy.utils.types.FloatJoyType.accept">
-<code class="sig-name descname">accept</code><a class="headerlink" href="#joy.utils.types.FloatJoyType.accept" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">builtins.float</span></code></p>
+<code class="descname">accept</code><a class="headerlink" href="#joy.utils.types.FloatJoyType.accept" title="Permalink to this definition">¶</a></dt>
+<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">__builtin__.float</span></code></p>
</dd></dl>
</dd></dl>
-<dl class="py class">
-<dt id="joy.utils.types.FloatStarJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">FloatStarJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#FloatStarJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.FloatStarJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
-<dt id="joy.utils.types.FloatStarJoyType.kind">
-<code class="sig-name descname">kind</code><a class="headerlink" href="#joy.utils.types.FloatStarJoyType.kind" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <a class="reference internal" href="#joy.utils.types.FloatJoyType" title="joy.utils.types.FloatJoyType"><code class="xref py py-class docutils literal notranslate"><span class="pre">FloatJoyType</span></code></a></p>
-</dd></dl>
-
-</dd></dl>
-
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.FunctionJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">FunctionJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">sec</span></em>, <em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#FunctionJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.FunctionJoyType" title="Permalink to this definition">¶</a></dt>
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">FunctionJoyType</code><span class="sig-paren">(</span><em>name</em>, <em>sec</em>, <em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#FunctionJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.FunctionJoyType" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.IntJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">IntJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#IntJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.IntJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">IntJoyType</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#IntJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.IntJoyType" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="attribute">
<dt id="joy.utils.types.IntJoyType.accept">
-<code class="sig-name descname">accept</code><a class="headerlink" href="#joy.utils.types.IntJoyType.accept" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">builtins.int</span></code></p>
-</dd></dl>
-
-</dd></dl>
-
-<dl class="py class">
-<dt id="joy.utils.types.IntStarJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">IntStarJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#IntStarJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.IntStarJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
-<dt id="joy.utils.types.IntStarJoyType.kind">
-<code class="sig-name descname">kind</code><a class="headerlink" href="#joy.utils.types.IntStarJoyType.kind" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <a class="reference internal" href="#joy.utils.types.IntJoyType" title="joy.utils.types.IntJoyType"><code class="xref py py-class docutils literal notranslate"><span class="pre">IntJoyType</span></code></a></p>
+<code class="descname">accept</code><a class="headerlink" href="#joy.utils.types.IntJoyType.accept" title="Permalink to this definition">¶</a></dt>
+<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">__builtin__.int</span></code></p>
</dd></dl>
</dd></dl>
-<dl class="py exception">
+<dl class="exception">
<dt id="joy.utils.types.JoyTypeError">
-<em class="property">exception </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">JoyTypeError</code><a class="reference internal" href="_modules/joy/utils/types.html#JoyTypeError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.JoyTypeError" title="Permalink to this definition">¶</a></dt>
+<em class="property">exception </em><code class="descclassname">joy.utils.types.</code><code class="descname">JoyTypeError</code><a class="reference internal" href="_modules/joy/utils/types.html#JoyTypeError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.JoyTypeError" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.KleeneStar">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">KleeneStar</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#KleeneStar"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.KleeneStar" title="Permalink to this definition">¶</a></dt>
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">KleeneStar</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#KleeneStar"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.KleeneStar" title="Permalink to this definition">¶</a></dt>
<dd><p>A sequence of zero or more <cite>AnyJoyType</cite> variables would be:</p>
<blockquote>
-<div><p>A*</p>
-</div></blockquote>
+<div>A*</div></blockquote>
<p>The <cite>A*</cite> works by splitting the universe into two alternate histories:</p>
<blockquote>
<div><p>A* → ∅</p>
it turns into an <cite>AnyJoyType</cite> variable followed by itself again.</p>
<p>We have to return all universes (represented by their substitution
dicts, the “unifiers”) that don’t lead to type conflicts.</p>
-<dl class="py attribute">
+<dl class="attribute">
<dt id="joy.utils.types.KleeneStar.kind">
-<code class="sig-name descname">kind</code><a class="headerlink" href="#joy.utils.types.KleeneStar.kind" title="Permalink to this definition">¶</a></dt>
+<code class="descname">kind</code><a class="headerlink" href="#joy.utils.types.KleeneStar.kind" title="Permalink to this definition">¶</a></dt>
<dd><p>alias of <a class="reference internal" href="#joy.utils.types.AnyJoyType" title="joy.utils.types.AnyJoyType"><code class="xref py py-class docutils literal notranslate"><span class="pre">AnyJoyType</span></code></a></p>
</dd></dl>
</dd></dl>
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.NumberJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">NumberJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#NumberJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.NumberJoyType" title="Permalink to this definition">¶</a></dt>
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">NumberJoyType</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#NumberJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.NumberJoyType" title="Permalink to this definition">¶</a></dt>
<dd></dd></dl>
-<dl class="py class">
-<dt id="joy.utils.types.NumberStarJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">NumberStarJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#NumberStarJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.NumberStarJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
-<dt id="joy.utils.types.NumberStarJoyType.kind">
-<code class="sig-name descname">kind</code><a class="headerlink" href="#joy.utils.types.NumberStarJoyType.kind" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <a class="reference internal" href="#joy.utils.types.NumberJoyType" title="joy.utils.types.NumberJoyType"><code class="xref py py-class docutils literal notranslate"><span class="pre">NumberJoyType</span></code></a></p>
-</dd></dl>
-
-</dd></dl>
-
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.StackJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">StackJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#StackJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.StackJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">StackJoyType</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#StackJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.StackJoyType" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="attribute">
<dt id="joy.utils.types.StackJoyType.accept">
-<code class="sig-name descname">accept</code><a class="headerlink" href="#joy.utils.types.StackJoyType.accept" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">builtins.tuple</span></code></p>
-</dd></dl>
-
-</dd></dl>
-
-<dl class="py class">
-<dt id="joy.utils.types.StackStarJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">StackStarJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#StackStarJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.StackStarJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
-<dt id="joy.utils.types.StackStarJoyType.kind">
-<code class="sig-name descname">kind</code><a class="headerlink" href="#joy.utils.types.StackStarJoyType.kind" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <a class="reference internal" href="#joy.utils.types.StackJoyType" title="joy.utils.types.StackJoyType"><code class="xref py py-class docutils literal notranslate"><span class="pre">StackJoyType</span></code></a></p>
+<code class="descname">accept</code><a class="headerlink" href="#joy.utils.types.StackJoyType.accept" title="Permalink to this definition">¶</a></dt>
+<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">__builtin__.tuple</span></code></p>
</dd></dl>
</dd></dl>
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.SymbolJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">SymbolJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">sec</span></em>, <em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#SymbolJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.SymbolJoyType" title="Permalink to this definition">¶</a></dt>
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">SymbolJoyType</code><span class="sig-paren">(</span><em>name</em>, <em>sec</em>, <em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#SymbolJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.SymbolJoyType" title="Permalink to this definition">¶</a></dt>
<dd><p>Represent non-combinator functions.</p>
<p>These type variables carry the stack effect comments and can
appear in expressions (as in quoted programs.)</p>
</dd></dl>
-<dl class="py class">
+<dl class="class">
<dt id="joy.utils.types.TextJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">TextJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#TextJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.TextJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
+<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">TextJoyType</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#TextJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.TextJoyType" title="Permalink to this definition">¶</a></dt>
+<dd><dl class="attribute">
<dt id="joy.utils.types.TextJoyType.accept">
-<code class="sig-name descname">accept</code><a class="headerlink" href="#joy.utils.types.TextJoyType.accept" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">past.types.basestring.basestring</span></code></p>
-</dd></dl>
-
+<code class="descname">accept</code><a class="headerlink" href="#joy.utils.types.TextJoyType.accept" title="Permalink to this definition">¶</a></dt>
+<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">__builtin__.basestring</span></code></p>
</dd></dl>
-<dl class="py class">
-<dt id="joy.utils.types.TextStarJoyType">
-<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">TextStarJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#TextStarJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.TextStarJoyType" title="Permalink to this definition">¶</a></dt>
-<dd><dl class="py attribute">
-<dt id="joy.utils.types.TextStarJoyType.kind">
-<code class="sig-name descname">kind</code><a class="headerlink" href="#joy.utils.types.TextStarJoyType.kind" title="Permalink to this definition">¶</a></dt>
-<dd><p>alias of <a class="reference internal" href="#joy.utils.types.TextJoyType" title="joy.utils.types.TextJoyType"><code class="xref py py-class docutils literal notranslate"><span class="pre">TextJoyType</span></code></a></p>
</dd></dl>
-</dd></dl>
-
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.compilable">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">compilable</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">f</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#compilable"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.compilable" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">compilable</code><span class="sig-paren">(</span><em>f</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#compilable"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.compilable" title="Permalink to this definition">¶</a></dt>
<dd><p>Return True if a stack effect represents a function that can be
automatically compiled (to Python), False otherwise.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.compile_">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">compile_</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">f</span></em>, <em class="sig-param"><span class="n">doc</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#compile_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.compile_" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">compile_</code><span class="sig-paren">(</span><em>name</em>, <em>f</em>, <em>doc=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#compile_"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.compile_" title="Permalink to this definition">¶</a></dt>
<dd><p>Return a string of Python code implementing the function described
by the stack effect. If no doc string is passed doc_from_stack_effect()
is used to generate one.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.compose">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">compose</code><span class="sig-paren">(</span><em class="sig-param"><span class="o">*</span><span class="n">functions</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#compose"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.compose" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">compose</code><span class="sig-paren">(</span><em>*functions</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#compose"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.compose" title="Permalink to this definition">¶</a></dt>
<dd><p>Return the stack effect of the composition of some of stack effects.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.delabel">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">delabel</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">f</span></em>, <em class="sig-param"><span class="n">seen</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">c</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#delabel"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.delabel" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">delabel</code><span class="sig-paren">(</span><em>f</em>, <em>seen=None</em>, <em>c=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#delabel"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.delabel" title="Permalink to this definition">¶</a></dt>
<dd><p>Fix up type variable numbers after relabel().</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.doc_from_stack_effect">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">doc_from_stack_effect</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inputs</span></em>, <em class="sig-param"><span class="n">outputs</span><span class="o">=</span><span class="default_value">'??', ()</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#doc_from_stack_effect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.doc_from_stack_effect" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">doc_from_stack_effect</code><span class="sig-paren">(</span><em>inputs</em>, <em>outputs=('??'</em>, <em>())</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#doc_from_stack_effect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.doc_from_stack_effect" title="Permalink to this definition">¶</a></dt>
<dd><p>Return a crude string representation of a stack effect.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.infer">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">infer</code><span class="sig-paren">(</span><em class="sig-param"><span class="o">*</span><span class="n">expression</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#infer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.infer" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">infer</code><span class="sig-paren">(</span><em>*expression</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#infer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.infer" title="Permalink to this definition">¶</a></dt>
<dd><p>Return a list of stack effects for a Joy expression.</p>
<p>For example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">h</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">rest</span><span class="p">,</span> <span class="n">cons</span><span class="p">,</span> <span class="n">cons</span><span class="p">)</span>
</div>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.meta_compose">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">meta_compose</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">F</span></em>, <em class="sig-param"><span class="n">G</span></em>, <em class="sig-param"><span class="n">e</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#meta_compose"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.meta_compose" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">meta_compose</code><span class="sig-paren">(</span><em>F</em>, <em>G</em>, <em>e</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#meta_compose"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.meta_compose" title="Permalink to this definition">¶</a></dt>
<dd><p>Yield the stack effects of the composition of two lists of stack
effects. An expression is carried along and updated and yielded.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.poly_compose">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">poly_compose</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">f</span></em>, <em class="sig-param"><span class="n">g</span></em>, <em class="sig-param"><span class="n">e</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#poly_compose"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.poly_compose" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">poly_compose</code><span class="sig-paren">(</span><em>f</em>, <em>g</em>, <em>e</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#poly_compose"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.poly_compose" title="Permalink to this definition">¶</a></dt>
<dd><p>Yield the stack effects of the composition of two stack effects. An
expression is carried along and updated and yielded.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.reify">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">reify</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">meaning</span></em>, <em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">seen</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#reify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.reify" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">reify</code><span class="sig-paren">(</span><em>meaning</em>, <em>name</em>, <em>seen=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#reify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.reify" title="Permalink to this definition">¶</a></dt>
<dd><p>Apply substitution dict to term, returning new term.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.relabel">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">relabel</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">left</span></em>, <em class="sig-param"><span class="n">right</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#relabel"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.relabel" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">relabel</code><span class="sig-paren">(</span><em>left</em>, <em>right</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#relabel"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.relabel" title="Permalink to this definition">¶</a></dt>
<dd><p>Re-number type variables to avoid collisions between stack effects.</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.type_check">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">type_check</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">name</span></em>, <em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#type_check"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.type_check" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">type_check</code><span class="sig-paren">(</span><em>name</em>, <em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#type_check"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.type_check" title="Permalink to this definition">¶</a></dt>
<dd><p>Trinary predicate. True if named function type-checks, False if it
fails, None if it’s indeterminate (because I haven’t entered it into
the FUNCTIONS dict yet.)</p>
</dd></dl>
-<dl class="py function">
+<dl class="function">
<dt id="joy.utils.types.uni_unify">
-<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">uni_unify</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">u</span></em>, <em class="sig-param"><span class="n">v</span></em>, <em class="sig-param"><span class="n">s</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#uni_unify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.uni_unify" title="Permalink to this definition">¶</a></dt>
+<code class="descclassname">joy.utils.types.</code><code class="descname">uni_unify</code><span class="sig-paren">(</span><em>u</em>, <em>v</em>, <em>s=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#uni_unify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.uni_unify" title="Permalink to this definition">¶</a></dt>
<dd><p>Return a substitution dict representing a unifier for u and v.</p>
</dd></dl>
</div>
-
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
-<h1 class="logo"><a href="index.html">Thun</a></h1>
-
-
-
-
-
-
-
-
-<h3>Navigation</h3>
-<ul class="current">
-<li class="toctree-l1"><a class="reference internal" href="notebooks/Intro.html">Thun: Joy in Python</a></li>
-<li class="toctree-l1"><a class="reference internal" href="joy.html">Joy Interpreter</a></li>
-<li class="toctree-l1"><a class="reference internal" href="stack.html">Stack or Quote or Sequence or List…</a></li>
-<li class="toctree-l1"><a class="reference internal" href="parser.html">Parsing Text into Joy Expressions</a></li>
-<li class="toctree-l1"><a class="reference internal" href="pretty.html">Tracing Joy Execution</a></li>
-<li class="toctree-l1"><a class="reference internal" href="library.html">Function Reference</a></li>
-<li class="toctree-l1"><a class="reference internal" href="lib.html">Functions Grouped by, er, Function with Examples</a></li>
-<li class="toctree-l1 current"><a class="current reference internal" href="#">Type Inference of Joy Expressions</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#joy-utils-types"><code class="docutils literal notranslate"><span class="pre">joy.utils.types</span></code></a></li>
+ <h3><a href="index.html">Table Of Contents</a></h3>
+ <ul>
+<li><a class="reference internal" href="#">Type Inference of Joy Expressions</a><ul>
+<li><a class="reference internal" href="#joy-utils-types"><code class="docutils literal notranslate"><span class="pre">joy.utils.types</span></code></a></li>
</ul>
</li>
-<li class="toctree-l1"><a class="reference internal" href="notebooks/index.html">Essays about Programming in Joy</a></li>
</ul>
-
<div class="relations">
<h3>Related Topics</h3>
<ul>
</ul></li>
</ul>
</div>
+ <div role="note" aria-label="source link">
+ <h3>This Page</h3>
+ <ul class="this-page-menu">
+ <li><a href="_sources/types.rst.txt"
+ rel="nofollow">Show Source</a></li>
+ </ul>
+ </div>
<div id="searchbox" style="display: none" role="search">
- <h3 id="searchlabel">Quick search</h3>
+ <h3>Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
- <input type="text" name="q" aria-labelledby="searchlabel" />
+ <input type="text" name="q" />
<input type="submit" value="Go" />
+ <input type="hidden" name="check_keywords" value="yes" />
+ <input type="hidden" name="area" value="default" />
</form>
</div>
</div>
-<script>$('#searchbox').show(0);</script>
-
-
-
-
-
-
-
-
+<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
- Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
+ Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>
∂RE
===
-Brzozowski's Derivatives of Regular Expressions
+Brzozowski’s Derivatives of Regular Expressions
-----------------------------------------------
Legend:
::
- ∧ intersection
- ∨ union
- ∘ concatenation (see below)
- ¬ complement
- ϕ empty set (aka ∅)
- λ singleton set containing just the empty string
- I set of all letters in alphabet
+ ∧ intersection
+ ∨ union
+ ∘ concatenation (see below)
+ ¬ complement
+ ϕ empty set (aka ∅)
+ λ singleton set containing just the empty string
+ I set of all letters in alphabet
Derivative of a set ``R`` of strings and a string ``a``:
::
- ∂a(R)
+ ∂a(R)
- ∂a(a) → λ
- ∂a(λ) → ϕ
- ∂a(ϕ) → ϕ
- ∂a(¬a) → ϕ
- ∂a(R*) → ∂a(R)∘R*
- ∂a(¬R) → ¬∂a(R)
- ∂a(R∘S) → ∂a(R)∘S ∨ δ(R)∘∂a(S)
- ∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
- ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
+ ∂a(a) → λ
+ ∂a(λ) → ϕ
+ ∂a(ϕ) → ϕ
+ ∂a(¬a) → ϕ
+ ∂a(R*) → ∂a(R)∘R*
+ ∂a(¬R) → ¬∂a(R)
+ ∂a(R∘S) → ∂a(R)∘S ∨ δ(R)∘∂a(S)
+ ∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
+ ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
- ∂ab(R) = ∂b(∂a(R))
+ ∂ab(R) = ∂b(∂a(R))
Auxiliary predicate function ``δ`` (I call it ``nully``) returns either
``λ`` if ``λ ⊆ R`` or ``ϕ`` otherwise:
::
- δ(a) → ϕ
- δ(λ) → λ
- δ(ϕ) → ϕ
- δ(R*) → λ
- δ(¬R) δ(R)≟ϕ → λ
- δ(¬R) δ(R)≟λ → ϕ
- δ(R∘S) → δ(R) ∧ δ(S)
- δ(R ∧ S) → δ(R) ∧ δ(S)
- δ(R ∨ S) → δ(R) ∨ δ(S)
+ δ(a) → ϕ
+ δ(λ) → λ
+ δ(ϕ) → ϕ
+ δ(R*) → λ
+ δ(¬R) δ(R)≟ϕ → λ
+ δ(¬R) δ(R)≟λ → ϕ
+ δ(R∘S) → δ(R) ∧ δ(S)
+ δ(R ∧ S) → δ(R) ∧ δ(S)
+ δ(R ∨ S) → δ(R) ∨ δ(S)
-Some rules we will use later for "compaction":
+Some rules we will use later for “compaction”:
::
- R ∧ ϕ = ϕ ∧ R = ϕ
+ R ∧ ϕ = ϕ ∧ R = ϕ
- R ∧ I = I ∧ R = R
+ R ∧ I = I ∧ R = R
- R ∨ ϕ = ϕ ∨ R = R
+ R ∨ ϕ = ϕ ∨ R = R
- R ∨ I = I ∨ R = I
+ R ∨ I = I ∨ R = I
- R∘ϕ = ϕ∘R = ϕ
+ R∘ϕ = ϕ∘R = ϕ
- R∘λ = λ∘R = R
+ R∘λ = λ∘R = R
Concatination of sets: for two sets A and B the set A∘B is defined as:
E.g.:
-{'a', 'b'}∘{'c', 'd'} → {'ac', 'ad', 'bc', 'bd'}
+{‘a’, ‘b’}∘{‘c’, ‘d’} → {‘ac’, ‘ad’, ‘bc’, ‘bd’}
Implementation
--------------
Two-letter Alphabet
~~~~~~~~~~~~~~~~~~~
-I'm only going to use two symbols (at first) becaase this is enough to
+I’m only going to use two symbols (at first) becaase this is enough to
illustrate the algorithm and because you can represent any other
alphabet with two symbols (if you had to.)
-I chose the names ``O`` and ``l`` (uppercase "o" and lowercase "L") to
+I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
look like ``0`` and ``1`` (zero and one) respectively.
.. code:: ipython2
Representing Regular Expressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-To represent REs in Python I'm going to use tagged tuples. A *regular
+To represent REs in Python I’m going to use tagged tuples. A *regular
expression* is one of:
::
- O
- l
- (KSTAR, R)
- (NOT, R)
- (AND, R, S)
- (CONS, R, S)
- (OR, R, S)
+ O
+ l
+ (KSTAR, R)
+ (NOT, R)
+ (AND, R, S)
+ (CONS, R, S)
+ (OR, R, S)
Where ``R`` and ``S`` stand for *regular expressions*.
``I``
~~~~~
-Match anything. Often spelled "."
+Match anything. Often spelled “.”
::
- I = (0|1)*
+ I = (0|1)*
.. code:: ipython2
::
- (.111.) & (.01 + 11*)'
- a & (b + c)'
+ (.111.) & (.01 + 11*)'
+ a & (b + c)'
Note that it contains one of everything.
``nully()``
~~~~~~~~~~~
-Let's get that auxiliary predicate function ``δ`` out of the way.
+Let’s get that auxiliary predicate function ``δ`` out of the way.
.. code:: ipython2
r, s = nully(R[1]), nully(R[2])
return r & s if tag in {AND, CONS} else r | s
-No "Compaction"
+No “Compaction”
~~~~~~~~~~~~~~~
-This is the straightforward version with no "compaction". It works fine,
+This is the straightforward version with no “compaction”. It works fine,
but does waaaay too much work because the expressions grow each
derivation.
result = self.mem[key] = self.f(key)
return result
-With "Compaction"
+With “Compaction”
~~~~~~~~~~~~~~~~~
This version uses the rules above to perform compaction. It keeps the
return derv
-Let's try it out...
--------------------
+Let’s try it out…
+-----------------
(FIXME: redo.)
::
- (.111.) & ((.01 | 11*)')
+ (.111.) & ((.01 | 11*)')
- 92 / 122
- 92 / 122
+ 92 / 122
+ 92 / 122
- (.01 )'
- (.01 | 1 )'
- (.01 | ^ )'
- (.01 | 1*)'
- (.111.) & ((.01 | 1 )')
- (.111. | 11.) & ((.01 | ^ )')
- (.111. | 11.) & ((.01 | 1*)')
- (.111. | 11. | 1.) & ((.01 )')
- (.111. | 11. | 1.) & ((.01 | 1*)')
+ (.01 )'
+ (.01 | 1 )'
+ (.01 | ^ )'
+ (.01 | 1*)'
+ (.111.) & ((.01 | 1 )')
+ (.111. | 11.) & ((.01 | ^ )')
+ (.111. | 11.) & ((.01 | 1*)')
+ (.111. | 11. | 1.) & ((.01 )')
+ (.111. | 11. | 1.) & ((.01 | 1*)')
Larger Alphabets
----------------
-We could parse larger alphabets by defining patterns for e.g. each byte
+We could parse larger alphabets by defining patterns for e.g. each byte
of the ASCII code. Or we can generalize this code. If you study the code
-above you'll see that we never use the "set-ness" of the symbols ``O``
+above you’ll see that we never use the “set-ness” of the symbols ``O``
and ``l``. The only time Python set operators (``&`` and ``|``) appear
is in the ``nully()`` function, and there they operate on (recursively
computed) outputs of that function, never ``O`` and ``l``.
::
- (OR, O, l)
+ (OR, O, l)
- ∂1((OR, O, l))
- ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
- ∂1(O) ∨ ∂1(l)
- ∂a(¬a) → ϕ
- ϕ ∨ ∂1(l)
- ∂a(a) → λ
- ϕ ∨ λ
- ϕ ∨ R = R
- λ
+ ∂1((OR, O, l))
+ ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
+ ∂1(O) ∨ ∂1(l)
+ ∂a(¬a) → ϕ
+ ϕ ∨ ∂1(l)
+ ∂a(a) → λ
+ ϕ ∨ λ
+ ϕ ∨ R = R
+ λ
And compare it to:
::
- {'0', '1')
+ {'0', '1')
- ∂1({'0', '1'))
- ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
- ∂1({'0')) ∨ ∂1({'1'))
- ∂a(¬a) → ϕ
- ϕ ∨ ∂1({'1'))
- ∂a(a) → λ
- ϕ ∨ λ
- ϕ ∨ R = R
- λ
+ ∂1({'0', '1'))
+ ∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
+ ∂1({'0')) ∨ ∂1({'1'))
+ ∂a(¬a) → ϕ
+ ϕ ∨ ∂1({'1'))
+ ∂a(a) → λ
+ ϕ ∨ λ
+ ϕ ∨ R = R
+ λ
This suggests that we should be able to alter the functions above to
detect sets and deal with them appropriately. Exercise for the Reader
::
- .111. & (.01 + 11*)'
+ .111. & (.01 + 11*)'
-Says, "Three or more 1's and not ending in 01 nor composed of all 1's."
+Says, “Three or more 1’s and not ending in 01 nor composed of all 1’s.”
.. figure:: attachment:omg.svg
:alt: omg.svg
Start at ``a`` and follow the transition arrows according to their
labels. Accepting states have a double outline. (Graphic generated with
-`Dot from Graphviz <http://www.graphviz.org/>`__.) You'll see that only
+`Dot from Graphviz <http://www.graphviz.org/>`__.) You’ll see that only
paths that lead to one of the accepting states will match the regular
expression. All other paths will terminate at one of the non-accepting
states.
-There's a happy path to ``g`` along 111:
+There’s a happy path to ``g`` along 111:
::
- a→c→e→g
+ a→c→e→g
-After you reach ``g`` you're stuck there eating 1's until you see a 0,
-which takes you to the ``i→j→i|i→j→h→i`` "trap". You can't reach any
+After you reach ``g`` you’re stuck there eating 1’s until you see a 0,
+which takes you to the ``i→j→i|i→j→h→i`` “trap”. You can’t reach any
other states from those two loops.
If you see a 0 before you see 111 you will reach ``b``, which forms
-another "trap" with ``d`` and ``f``. The only way out is another happy
+another “trap” with ``d`` and ``f``. The only way out is another happy
path along 111 to ``h``:
::
- b→d→f→h
+ b→d→f→h
-Once you have reached ``h`` you can see as many 1's or as many 0' in a
-row and still be either still at ``h`` (for 1's) or move to ``i`` (for
-0's). If you find yourself at ``i`` you can see as many 0's, or
+Once you have reached ``h`` you can see as many 1’s or as many 0’ in a
+row and still be either still at ``h`` (for 1’s) or move to ``i`` (for
+0’s). If you find yourself at ``i`` you can see as many 0’s, or
repetitions of 10, as there are, but if you see just a 1 you move to
``j``.
So how do we get the state machine from the regular expression?
It turns out that each RE is effectively a state, and each arrow points
-to the derivative RE in respect to the arrow's symbol.
+to the derivative RE in respect to the arrow’s symbol.
If we label the initial RE ``a``, we can say:
::
- a --0--> ∂0(a)
- a --1--> ∂1(a)
+ a --0--> ∂0(a)
+ a --1--> ∂1(a)
And so on, each new unique RE is a new state in the FSM table.
::
- a = (.111.) & ((.01 | 11*)')
- b = (.111.) & ((.01 | 1)')
- c = (.111. | 11.) & ((.01 | 1*)')
- d = (.111. | 11.) & ((.01 | ^)')
- e = (.111. | 11. | 1.) & ((.01 | 1*)')
- f = (.111. | 11. | 1.) & ((.01)')
- g = (.01 | 1*)'
- h = (.01)'
- i = (.01 | 1)'
- j = (.01 | ^)'
-
-You can see the one-way nature of the ``g`` state and the ``hij`` "trap"
+ a = (.111.) & ((.01 | 11*)')
+ b = (.111.) & ((.01 | 1)')
+ c = (.111. | 11.) & ((.01 | 1*)')
+ d = (.111. | 11.) & ((.01 | ^)')
+ e = (.111. | 11. | 1.) & ((.01 | 1*)')
+ f = (.111. | 11. | 1.) & ((.01)')
+ g = (.01 | 1*)'
+ h = (.01)'
+ i = (.01 | 1)'
+ j = (.01 | ^)'
+
+You can see the one-way nature of the ``g`` state and the ``hij`` “trap”
in the way that the ``.111.`` on the left-hand side of the ``&``
disappears once it has been matched.
There are *lots* of FSM libraries already. Once you have the state
transition table they should all be straightforward to use. State
Machine code is very simple. Just for fun, here is an implementation in
-Python that imitates what "compiled" FSM code might look like in an
-"unrolled" form. Most FSM code uses a little driver loop and a table
+Python that imitates what “compiled” FSM code might look like in an
+“unrolled” form. Most FSM code uses a little driver loop and a table
datastructure, the code below instead acts like JMP instructions
-("jump", or GOTO in higher-level-but-still-low-level languages) to
+(“jump”, or GOTO in higher-level-but-still-low-level languages) to
hard-code the information in the table into a little patch of branches.
Trampoline Function
^^^^^^^^^^^^^^^^^^^
-Python has no GOTO statement but we can fake it with a "trampoline"
+Python has no GOTO statement but we can fake it with a “trampoline”
function.
.. code:: ipython2
Stream Functions
^^^^^^^^^^^^^^^^
-Little helpers to process the iterator of our data (a "stream" of "1"
-and "0" characters, not bits.)
+Little helpers to process the iterator of our data (a “stream” of “1”
+and “0” characters, not bits.)
.. code:: ipython2
Note that the implementations of ``h`` and ``g`` are identical ergo
``h = g`` and we could eliminate one in the code but ``h`` is an
-accepting state and ``g`` isn't.
+accepting state and ``g`` isn’t.
.. code:: ipython2
------------------------------------------------------
(UNFINISHED) Brzozowski also shewed how to go from the state machine to
-strings and expressions...
+strings and expressions…
Each of these states is just a name for a Brzozowskian RE, and so, other
than the initial state ``a``, they can can be described in terms of the
::
- c = d1(a)
- b = d0(a)
- b = d0(c)
- ...
- i = d0(j)
- j = d1(i)
+ c = d1(a)
+ b = d0(a)
+ b = d0(c)
+ ...
+ i = d0(j)
+ j = d1(i)
Consider:
::
- c = d1(a)
- b = d0(c)
+ c = d1(a)
+ b = d0(c)
Substituting:
::
- b = d0(d1(a))
+ b = d0(d1(a))
Unwrapping:
::
- b = d10(a)
+ b = d10(a)
-'''
+’’’
::
- j = d1(d0(j))
+ j = d1(d0(j))
Unwrapping:
::
- j = d1(d0(j)) = d01(j)
+ j = d1(d0(j)) = d01(j)
-We have a loop or "fixed point".
+We have a loop or “fixed point”.
::
- j = d01(j) = d0101(j) = d010101(j) = ...
+ j = d01(j) = d0101(j) = d010101(j) = ...
-hmm...
+hmm…
::
- j = (01)*
+ j = (01)*
::
- x == dup i
+ x == dup i
We can apply it to a quoted program consisting of some value ``a`` and
some function ``B``:
::
- [a B] x
- [a B] a B
+ [a B] x
+ [a B] a B
Let ``B`` function ``swap`` the ``a`` with the quote and run some
function ``C`` on it to generate a new value ``b``:
::
- B == swap [C] dip
+ B == swap [C] dip
- [a B] a B
- [a B] a swap [C] dip
- a [a B] [C] dip
- a C [a B]
- b [a B]
+ [a B] a B
+ [a B] a swap [C] dip
+ a [a B] [C] dip
+ a C [a B]
+ b [a B]
Now discard the quoted ``a`` with ``rest`` then ``cons`` ``b``:
::
- b [a B] rest cons
- b [B] cons
- [b B]
+ b [a B] rest cons
+ b [B] cons
+ [b B]
Altogether, this is the definition of ``B``:
::
- B == swap [C] dip rest cons
+ B == swap [C] dip rest cons
-We can make a generator for the Natural numbers (0, 1, 2, ...) by using
+We can make a generator for the Natural numbers (0, 1, 2, …) by using
``0`` for ``a`` and ``[dup ++]`` for ``[C]``:
::
- [0 swap [dup ++] dip rest cons]
+ [0 swap [dup ++] dip rest cons]
-Let's try it:
+Let’s try it:
.. code:: ipython2
::
- a [C] G
- -------------------------
- [a swap [C] direco]
+ a [C] G
+ -------------------------
+ [a swap [C] direco]
Working in reverse:
::
- [a swap [C] direco] cons
- a [swap [C] direco] concat
- a [swap] [[C] direco] swap
- a [[C] direco] [swap]
- a [C] [direco] cons [swap]
+ [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
+ G == [direco] cons [swap] swap concat cons
+ G == [direco] cons [swap] swoncat cons
.. code:: ipython2
define('G == [direco] cons [swap] swoncat cons')
-Let's try it out:
+Let’s try it out:
.. code:: ipython2
--------------------------------------
Look at the treatment of the Project Euler Problem One in the
-"Developing a Program" notebook and you'll see that we might be
+“Developing a Program” notebook and you’ll see that we might be
interested in generating an endless cycle of:
::
- 3 2 1 3 1 2 3
+ 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
+ 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.
3 3702 .
-If we plug ``14811`` and ``[PE1.1]`` into our generator form...
+If we plug ``14811`` and ``[PE1.1]`` into our generator form…
.. code:: ipython2
[14811 swap [PE1.1] direco]
-...we get a generator that works for seven cycles before it reaches
-zero:
+…we get a generator that works for seven cycles before it reaches zero:
.. code:: ipython2
(It would be more efficient to reset the int every seven cycles but
-that's a little beyond the scope of this article. This solution does
-extra work, but not much, and we're not using it "in production" as they
+that’s a little beyond the scope of this article. This solution does
+extra work, but not much, and we’re not using it “in production” as they
say.)
Run 466 times
~~~~~~~~~~~~~
In the PE1 problem we are asked to sum all the multiples of three and
-five less than 1000. It's worked out that we need to use all seven
+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
::
- [b a F] x
- [b a F] b a F
+ [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
+ [b a F] b a +
+ [b a F] b+a
From here we want to arrive at:
::
- b [b+a b F]
+ b [b+a b F]
-Let's start with ``swons``:
+Let’s start with ``swons``:
::
- [b a F] b+a swons
- [b+a b a F]
+ [b a F] b+a swons
+ [b+a b a F]
Considering this quote as a stack:
::
- F a b b+a
+ F a b b+a
We want to get it to:
::
- F b b+a b
+ F b b+a b
So:
::
- F a b b+a popdd over
- F b b+a b
+ 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]
+ [b+a b a F] [popdd over] infra
+ [b b+a b F]
But we can just use ``cons`` to carry ``b+a`` into the quote:
::
- [b a F] b+a [popdd over] cons infra
- [b a F] [b+a popdd over] infra
- [b b+a b F]
+ [b a F] b+a [popdd over] cons infra
+ [b a F] [b+a popdd over] infra
+ [b b+a b F]
Lastly:
::
- [b b+a b F] uncons
- b [b+a b F]
+ [b b+a b F] uncons
+ b [b+a b F]
Putting it all together:
::
- F == + [popdd over] cons infra uncons
- fib_gen == [1 1 F]
+ F == + [popdd over] cons infra uncons
+ fib_gen == [1 1 F]
.. code:: ipython2
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.
+ 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
define('PE2.1 == dup 2 % [+] [pop] branch')
And a predicate function that detects when the terms in the series
-"exceed four million".
+“exceed four million”.
.. code:: ipython2
define('>4M == 4000000 >')
-Now it's straightforward to define ``PE2`` as a recursive function that
+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.
4613732
-Here's the collected program definitions:
+Here’s the collected program definitions:
::
- fib == + swons [popdd over] infra uncons
- fib_gen == [1 1 fib]
+ fib == + swons [popdd over] infra uncons
+ fib_gen == [1 1 fib]
- even == dup 2 %
- >4M == 4000000 >
+ even == dup 2 %
+ >4M == 4000000 >
- PE2.1 == even [+] [pop] branch
- PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
+ PE2.1 == even [+] [pop] branch
+ PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
Even-valued Fibonacci Terms
~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- o + o = e
- e + e = e
- o + e = o
+ 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 . . .
+ 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.
::
- $ python -m joy
- Joypy - Copyright © 2017 Simon Forman
+ $ python3 -m joy
+ Thun - Copyright © 2017 Simon Forman
This program comes with ABSOLUTELY NO WARRANTY; for details type "warranty".
This is free software, and you are welcome to redistribute it
under certain conditions; type "sharing" for details.
docs for a word.
- <-top
+ <-top
joy? _
be printed followed by the stack and prompt again::
joy? 23 sqr 18 +
- . 23 sqr 18 +
+
+ 547 <-top
+
+ joy?
+
+There is a `trace` combinator::
+
+ joy? 23 [sqr 18 +] trace
23 . sqr 18 +
23 . dup mul 18 +
23 23 . mul 18 +
-`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
+`Newton’s method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
=====================================================================
-Let's use the Newton-Raphson method for finding the root of an equation
+Let’s use the Newton-Raphson method for finding the root of an equation
to write a function that can compute the square root of a number.
-Cf. `"Why Functional Programming Matters" by John
+Cf. `“Why Functional Programming Matters” by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
.. code:: ipython2
::
- a F
- ---------
- a'
+ a F
+ ---------
+ a'
A Function to Compute the Next Approximation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- a n over / + 2 /
- a n a / + 2 /
- a n/a + 2 /
- a+n/a 2 /
- (a+n/a)/2
+ a n over / + 2 /
+ a n a / + 2 /
+ a n/a + 2 /
+ a+n/a 2 /
+ (a+n/a)/2
The function we want has the argument ``n`` in it:
::
- F == n over / + 2 /
+ F == n over / + 2 /
Make it into a Generator
~~~~~~~~~~~~~~~~~~~~~~~~
::
- a [dup F] make_generator
+ a [dup F] make_generator
With n as part of the function F, but n is the input to the sqrt
function we’re writing. If we let 1 be the initial approximation:
::
- 1 n 1 / + 2 /
- 1 n/1 + 2 /
- 1 n + 2 /
- n+1 2 /
- (n+1)/2
+ 1 n 1 / + 2 /
+ 1 n/1 + 2 /
+ 1 n + 2 /
+ n+1 2 /
+ (n+1)/2
The generator can be written as:
::
- 23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
- 1 23 [over / + 2 /] cons [dup] swoncat make_generator
- 1 [23 over / + 2 /] [dup] swoncat make_generator
- 1 [dup 23 over / + 2 /] make_generator
+ 23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
+ 1 23 [over / + 2 /] cons [dup] swoncat make_generator
+ 1 [23 over / + 2 /] [dup] swoncat make_generator
+ 1 [dup 23 over / + 2 /] make_generator
.. code:: ipython2
[1 [dup 23 over / + 2 /] codireco]
-Let's drive the generator a few time (with the ``x`` combinator) and
-square the approximation to see how well it works...
+Let’s drive the generator a few time (with the ``x`` combinator) and
+square the approximation to see how well it works…
.. code:: ipython2
Finding Consecutive Approximations within a Tolerance
-----------------------------------------------------
-From `"Why Functional Programming Matters" by John
+From `“Why Functional Programming Matters” by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__:
- The remainder of a square root finder is a function *within*, which
- takes a tolerance and a list of approximations and looks down the
- list for two successive approximations that differ by no more than
- the given tolerance.
+ The remainder of a square root finder is a function *within*, which
+ takes a tolerance and a list of approximations and looks down the
+ list for two successive approximations that differ by no more than
+ the given tolerance.
(And note that by “list” he means a lazily-evaluated list.)
Using the *output* ``[a G]`` of the above generator for square root
approximations, and further assuming that the first term a has been
-generated already and epsilon ε is handy on the stack...
+generated already and epsilon ε is handy on the stack…
::
- a [b G] ε within
- ---------------------- a b - abs ε <=
- b
+ a [b G] ε within
+ ---------------------- a b - abs ε <=
+ b
- a [b G] ε within
- ---------------------- a b - abs ε >
- b [c G] ε within
+ a [b G] ε within
+ ---------------------- a b - abs ε >
+ b [c G] ε within
Predicate
~~~~~~~~~
::
- a [b G] ε [first - abs] dip <=
- a [b G] first - abs ε <=
- a b - abs ε <=
- a-b abs ε <=
- abs(a-b) ε <=
- (abs(a-b)<=ε)
+ a [b G] ε [first - abs] dip <=
+ a [b G] first - abs ε <=
+ a b - abs ε <=
+ a-b abs ε <=
+ abs(a-b) ε <=
+ (abs(a-b)<=ε)
.. code:: ipython2
::
- a [b G] ε roll< popop first
- [b G] ε a popop first
- [b G] first
- b
+ a [b G] ε roll< popop first
+ [b G] ε a popop first
+ [b G] first
+ b
.. code:: ipython2
::
- a [b G] ε R0 [within] R1
+ a [b G] ε R0 [within] R1
1. Discard a.
2. Use ``x`` combinator to generate next term from ``G``.
::
- a [b G] ε R0 [within] R1
- a [b G] ε [popd x] dip [within] i
- a [b G] popd x ε [within] i
- [b G] x ε [within] i
- b [c G] ε [within] i
- b [c G] ε within
+ a [b G] ε R0 [within] R1
+ a [b G] ε [popd x] dip [within] i
+ a [b G] popd x ε [within] i
+ [b G] x ε [within] i
+ b [c G] ε [within] i
+ b [c G] ε within
- b [c G] ε within
+ b [c G] ε within
.. code:: ipython2
::
- [a G] x ε ...
- a [b G] ε ...
+ [a G] x ε ...
+ a [b G] ε ...
.. code:: ipython2
define('within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec')
define('sqrt == gsra within')
-Try it out...
+Try it out…
.. code:: ipython2
::
- Tree :: [] | [key value Tree Tree]
+ Tree :: [] | [key value Tree Tree]
That says that a Tree is either the empty quote ``[]`` or a quote with
four items: a key, a value, and two Trees representing the left and
right branches of the tree.
-We're going to derive some recursive functions to work with such
+We’re going to derive some recursive functions to work with such
datastructures:
::
- Tree-add
- Tree-delete
- Tree-get
- Tree-iter
- Tree-iter-order
+ Tree-add
+ Tree-delete
+ Tree-get
+ Tree-iter
+ Tree-iter-order
-Once these functions are defined we have a new "type" to work with, and
+Once these functions are defined we have a new “type” to work with, and
the Sufficiently Smart Compiler can be modified to use an optimized
-implementation under the hood. (Where does the "type" come from? It has
+implementation under the hood. (Where does the “type” come from? It has
a contingent existence predicated on the disciplined use of these
functions on otherwise undistinguished Joy datastructures.)
Adding Nodes to the Tree
------------------------
-Let's consider adding nodes to a Tree structure.
+Let’s consider adding nodes to a Tree structure.
::
- Tree value key Tree-add
- -----------------------------
- Tree′
+ Tree value key Tree-add
+ -----------------------------
+ Tree′
Adding to an empty node.
~~~~~~~~~~~~~~~~~~~~~~~~
::
- Tree-add == [popop not] [[pop] dipd Tree-new] [R0] [R1] genrec
+ Tree-add == [popop not] [[pop] dipd Tree-new] [R0] [R1] genrec
``Tree-new``
^^^^^^^^^^^^
::
- value key Tree-new
- ------------------------
- [key value [] []]
+ value key Tree-new
+ ------------------------
+ [key value [] []]
Example:
::
- value key swap [[] []] cons cons
- key value [[] []] cons cons
- key [value [] []] cons
- [key value [] []]
+ value key swap [[] []] cons cons
+ key value [[] []] cons cons
+ key [value [] []] cons
+ [key value [] []]
Definition:
::
- Tree-new == swap [[] []] cons cons
+ Tree-new == swap [[] []] cons cons
.. code:: ipython2
(As an implementation detail, the ``[[] []]`` literal used in the
definition of ``Tree-new`` will be reused to supply the *constant* tail
for *all* new nodes produced by it. This is one of those cases where you
-get amortized storage "for free" by using `persistent
+get amortized storage “for free” by using `persistent
datastructures <https://en.wikipedia.org/wiki/Persistent_data_structure>`__.
Because the tail, which is ``((), ((), ()))`` in Python, is immutable
and embedded in the definition body for ``Tree-new``, all new nodes can
::
- [key_n value_n left right] value key R0 [Tree-add] R1
+ [key_n value_n left right] value key R0 [Tree-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
+less than or equal to the node’s key. In two of those cases we will need
to apply a copy of ``Tree-add``, so ``R0`` is pretty much out of the
picture.
::
- [R0] == []
+ [R0] == []
A predicate to compare keys.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [key_n value_n left right] value key [BTree-add] R1
+ [key_n value_n left right] value key [BTree-add] R1
-The first thing we need to do is compare the the key we're adding to the
+The first thing we need to do is compare the the key we’re adding to the
node key and ``branch`` accordingly:
::
- [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] [T] [E] ifte
That would suggest something like:
::
- [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
+ [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
-Let's abstract the predicate just a little to let us specify the
+Let’s abstract the predicate just a little to let us specify the
comparison operator:
::
- P > == pop roll> pop first >
- P < == pop roll> pop first <
- P == pop roll> pop first
+ P > == pop roll> pop first >
+ P < == pop roll> pop first <
+ P == pop roll> pop first
.. code:: ipython2
'new_key' 'old_key'
-If the key we're adding is greater than the node's key.
+If the key we’re adding is greater than the node’s key.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Here the parentheses are meant to signify that the expression is not
::
- [key_n value_n left right] value key [Tree-add] T
- -------------------------------------------------------
- [key_n value_n left (Tree-add key value right)]
+ [key_n value_n left right] value key [Tree-add] T
+ -------------------------------------------------------
+ [key_n value_n left (Tree-add key value right)]
-So how do we do this? We're going to want to use ``infra`` on some
+So how do we do this? 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 ``Tree-add`` to apply somehow. Considering the node as a
stack:
::
- right left value_n key_n value key [Tree-add] K
- -----------------------------------------------------
- right value key Tree-add left value_n key_n
+ right left value_n key_n value key [Tree-add] K
+ -----------------------------------------------------
+ right value key Tree-add left value_n key_n
Pretty easy:
::
- right left value_n key_n value key [Tree-add] cons cons dipdd
- right left value_n key_n [value key Tree-add] dipdd
- right value key Tree-add left value_n key_n
+ right left value_n key_n value key [Tree-add] cons cons dipdd
+ right left value_n key_n [value key Tree-add] dipdd
+ right value key Tree-add left value_n key_n
So:
::
- K == cons cons dipdd
+ K == cons cons dipdd
Looking at it from the point-of-view of the node as node again:
::
- [key_n value_n left right] [value key [Tree-add] K] infra
+ [key_n value_n left right] [value key [Tree-add] K] infra
Expand ``K`` and evaluate a little:
::
- [key_n value_n left right] [value key [Tree-add] K] infra
- [key_n value_n left right] [value key [Tree-add] cons cons dipdd] infra
- [key_n value_n left right] [[value key Tree-add] dipdd] infra
+ [key_n value_n left right] [value key [Tree-add] K] infra
+ [key_n value_n left right] [value key [Tree-add] cons cons dipdd] infra
+ [key_n value_n left right] [[value key Tree-add] dipdd] infra
Then, working backwards:
::
- [key_n value_n left right] [[value key Tree-add] dipdd] infra
- [key_n value_n left right] [value key Tree-add] [dipdd] cons infra
- [key_n value_n left right] value key [Tree-add] cons cons [dipdd] cons infra
+ [key_n value_n left right] [[value key Tree-add] dipdd] infra
+ [key_n value_n left right] [value key Tree-add] [dipdd] cons infra
+ [key_n value_n left right] value key [Tree-add] cons cons [dipdd] cons infra
And so ``T`` is just:
::
- T == cons cons [dipdd] cons infra
+ T == cons cons [dipdd] cons infra
.. code:: ipython2
['old_k' 'old_value' 'left' 'Tree-add' 'new_key' 'new_value' 'right']
-If the key we're adding is less than the node's key.
+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 [Tree-add] E
- [key_n value_n left right] value key [Tree-add] [P <] [Te] [Ee] ifte
+ [key_n value_n left right] value key [Tree-add] E
+ [key_n value_n left right] value key [Tree-add] [P <] [Te] [Ee] ifte
.. code:: ipython2
::
- Te == cons cons [dipd] cons infra
+ Te == cons cons [dipd] cons infra
.. code:: ipython2
::
- [key old_value left right] new_value key [Tree-add] Ee
- ------------------------------------------------------------
- [key new_value left right]
+ [key old_value left right] new_value key [Tree-add] Ee
+ ------------------------------------------------------------
+ [key new_value left right]
This is another easy one:
::
- Ee == pop swap roll< rest rest cons cons
+ Ee == pop swap roll< rest rest cons cons
Example:
::
- [key old_value left right] new_value key [Tree-add] pop swap roll< rest rest cons cons
- [key old_value left right] new_value key swap roll< rest rest cons cons
- [key old_value left right] key new_value roll< rest rest cons cons
- key new_value [key old_value left right] rest rest cons cons
- key new_value [ left right] cons cons
- [key new_value left right]
+ [key old_value left right] new_value key [Tree-add] pop swap roll< rest rest cons cons
+ [key old_value left right] new_value key swap roll< rest rest cons cons
+ [key old_value left right] key new_value roll< rest rest cons cons
+ key new_value [key old_value left right] rest rest cons cons
+ key new_value [ left right] cons cons
+ [key new_value left right]
.. code:: ipython2
::
- Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec
+ Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec
Putting it all together:
::
- Tree-new == swap [[] []] cons cons
- P == pop roll> pop first
- T == cons cons [dipdd] cons infra
- Te == cons cons [dipd] cons infra
- Ee == pop swap roll< rest rest cons cons
- E == [P <] [Te] [Ee] ifte
- R == [P >] [T] [E] ifte
+ Tree-new == swap [[] []] cons cons
+ P == pop roll> pop first
+ T == cons cons [dipdd] cons infra
+ Te == cons cons [dipd] cons infra
+ Ee == pop swap roll< rest rest cons cons
+ E == [P <] [Te] [Ee] ifte
+ R == [P >] [T] [E] ifte
- Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
+ Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
.. code:: ipython2
Interlude: ``cmp`` combinator
-----------------------------
-Instead of mucking about with nested ``ifte`` combinators let's use
+Instead of mucking about with nested ``ifte`` combinators let’s use
``cmp`` which takes two values and three quoted programs on the stack
and runs one of the three depending on the results of comparing the two
values:
::
- a b [G] [E] [L] cmp
- ------------------------- a > b
- G
+ 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
+ E
- a b [G] [E] [L] cmp
- ------------------------- a < b
- L
+ a b [G] [E] [L] cmp
+ ------------------------- a < b
+ L
.. code:: ipython2
::
- [node_key node_value left right] value key [Tree-add] P
- ------------------------------------------------------------------------
- [node_key node_value left right] value key [Tree-add] key node_key
+ [node_key node_value left right] value key [Tree-add] P
+ ------------------------------------------------------------------------
+ [node_key node_value left right] value key [Tree-add] key node_key
-Let's start with ``over`` to get a copy of the key and then apply some
+Let’s start with ``over`` to get a copy of the key and then apply some
function ``Q`` with the ``nullary`` combinator so it can dig out the
node key (by throwing everything else away):
::
- P == over [Q] nullary
+ P == over [Q] nullary
- [node_key node_value left right] value key [Tree-add] over [Q] nullary
- [node_key node_value left right] value key [Tree-add] key [Q] nullary
+ [node_key node_value left right] value key [Tree-add] over [Q] nullary
+ [node_key node_value left right] value key [Tree-add] key [Q] nullary
And ``Q`` would be:
::
- Q == popop popop first
+ Q == popop popop first
- [node_key node_value left right] value key [Tree-add] key Q
- [node_key node_value left right] value key [Tree-add] key popop popop first
- [node_key node_value left right] value key popop first
- [node_key node_value left right] first
- node_key
+ [node_key node_value left right] value key [Tree-add] key Q
+ [node_key node_value left right] value key [Tree-add] key popop popop first
+ [node_key node_value left right] value key popop first
+ [node_key node_value left right] first
+ node_key
Or just:
::
- P == over [popop popop first] nullary
+ P == over [popop popop first] nullary
.. code:: ipython2
::
- [node_key node_value left right] value key [Tree-add] R1
- [node_key node_value left right] value key [Tree-add] P [T] [E] [Te] cmp
+ [node_key node_value left right] value key [Tree-add] R1
+ [node_key node_value left right] value key [Tree-add] P [T] [E] [Te] cmp
The line above becomes one of the three lines below:
::
- [node_key node_value left right] value key [Tree-add] T
- [node_key node_value left right] value key [Tree-add] E
- [node_key node_value left right] value key [Tree-add] Te
+ [node_key node_value left right] value key [Tree-add] T
+ [node_key node_value left right] value key [Tree-add] E
+ [node_key node_value left right] value key [Tree-add] Te
The definition is a little longer but, I think, more elegant and easier
to understand:
::
- Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec
+ Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec
.. code:: ipython2
A Function to Traverse this Structure
-------------------------------------
-Let's take a crack at writing a function that can recursively iterate or
+Let’s take a crack at writing a function that can recursively iterate or
traverse these trees.
Base case ``[]``
::
- Tree-iter == [not] [E] [R0] [R1] genrec
+ Tree-iter == [not] [E] [R0] [R1] genrec
-And since there's nothing at this node, we just ``pop`` it:
+And since there’s nothing at this node, we just ``pop`` it:
::
- Tree-iter == [not] [pop] [R0] [R1] genrec
+ Tree-iter == [not] [pop] [R0] [R1] genrec
Node case ``[key value left right]``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- Tree-iter == [not] [pop] [R0] [R1] genrec
- == [not] [pop] [R0 [Tree-iter] R1] ifte
+ Tree-iter == [not] [pop] [R0] [R1] genrec
+ == [not] [pop] [R0 [Tree-iter] R1] ifte
-Let's look at it *in situ*:
+Let’s look at it *in situ*:
::
- [key value left right] R0 [Tree-iter] R1
+ [key value left right] R0 [Tree-iter] R1
Processing the current node.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [key value left right] [F] dupdip [Tree-iter] R1
- [key value left right] F [key value left right] [Tree-iter] R1
+ [key value left right] [F] dupdip [Tree-iter] R1
+ [key value left right] F [key value left right] [Tree-iter] R1
-For example, if we're getting all the keys ``F`` would be ``first``:
+For example, if we’re getting all the keys ``F`` would be ``first``:
::
- R0 == [first] dupdip
+ R0 == [first] dupdip
- [key value left right] [first] dupdip [Tree-iter] R1
- [key value left right] first [key value left right] [Tree-iter] R1
- key [key value left right] [Tree-iter] R1
+ [key value left right] [first] dupdip [Tree-iter] R1
+ [key value left right] first [key value left right] [Tree-iter] R1
+ key [key value left right] [Tree-iter] R1
Recur
^^^^^
::
- key [key value left right] [Tree-iter] R1
- key [key value left right] [Tree-iter] [rest rest] dip
- key [key value left right] rest rest [Tree-iter]
- key [left right] [Tree-iter]
+ key [key value left right] [Tree-iter] R1
+ key [key value left right] [Tree-iter] [rest rest] dip
+ key [key value left right] rest rest [Tree-iter]
+ key [left right] [Tree-iter]
Hmm, will ``step`` do?
::
- key [left right] [Tree-iter] step
- key left Tree-iter [right] [Tree-iter] step
- key left-keys [right] [Tree-iter] step
- key left-keys right Tree-iter
- key left-keys right-keys
+ key [left right] [Tree-iter] step
+ key left Tree-iter [right] [Tree-iter] step
+ key left-keys [right] [Tree-iter] step
+ key left-keys right Tree-iter
+ key left-keys right-keys
Neat. So:
::
- R1 == [rest rest] dip step
+ R1 == [rest rest] dip step
Putting it together
~~~~~~~~~~~~~~~~~~~
::
- Tree-iter == [not] [pop] [[F] dupdip] [[rest rest] dip step] genrec
+ Tree-iter == [not] [pop] [[F] dupdip] [[rest rest] dip step] genrec
When I was reading this over I realized ``rest rest`` could go in
``R0``:
::
- Tree-iter == [not] [pop] [[F] dupdip rest rest] [step] genrec
+ Tree-iter == [not] [pop] [[F] dupdip rest rest] [step] genrec
(And ``[step] genrec`` is such a cool and suggestive combinator!)
::
- [F] Tree-iter
- ------------------------------------------------------
- [not] [pop] [[F] dupdip rest rest] [step] genrec
+ [F] Tree-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
+ [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
``Tree-iter``
~~~~~~~~~~~~~
::
- Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec
+ Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec
.. code:: ipython2
-----------------------------------
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 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.
::
- Tree-iter-order == [not] [pop] [R0] [R1] genrec
+ Tree-iter-order == [not] [pop] [R0] [R1] genrec
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
+ [key value left right] R0 [BTree-iter-order] R1
Process the left child.
~~~~~~~~~~~~~~~~~~~~~~~
::
- [key value left right] R0 [Tree-iter-order] R1
- [key value left right] dup third [Tree-iter-order] R1
- [key value left right] left [Tree-iter-order] R1
+ [key value left right] R0 [Tree-iter-order] R1
+ [key value left right] dup third [Tree-iter-order] R1
+ [key value left right] left [Tree-iter-order] R1
Now maybe:
::
- [key value left right] left [Tree-iter-order] [cons dip] dupdip
- [key value left right] left [Tree-iter-order] cons dip [Tree-iter-order]
- [key value left right] [left Tree-iter-order] dip [Tree-iter-order]
- left Tree-iter-order [key value left right] [Tree-iter-order]
+ [key value left right] left [Tree-iter-order] [cons dip] dupdip
+ [key value left right] left [Tree-iter-order] cons dip [Tree-iter-order]
+ [key value left right] [left Tree-iter-order] dip [Tree-iter-order]
+ left Tree-iter-order [key value left right] [Tree-iter-order]
Process the current node.
~~~~~~~~~~~~~~~~~~~~~~~~~
-So far, so good. Now we need to process the current node's values:
+So far, so good. Now we need to process the current node’s values:
::
- left Tree-iter-order [key value left right] [Tree-iter-order] [[F] dupdip] dip
- left Tree-iter-order [key value left right] [F] dupdip [Tree-iter-order]
- left Tree-iter-order [key value left right] F [key value left right] [Tree-iter-order]
+ left Tree-iter-order [key value left right] [Tree-iter-order] [[F] dupdip] dip
+ left Tree-iter-order [key value left right] [F] dupdip [Tree-iter-order]
+ left Tree-iter-order [key value left right] F [key value left right] [Tree-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.
+``cons``\ ’d them before beginning maybe? For functions like ``first``
+it works fine as-is.
::
- left Tree-iter-order [key value left right] first [key value left right] [Tree-iter-order]
- left Tree-iter-order key [key value left right] [Tree-iter-order]
+ left Tree-iter-order [key value left right] first [key value left right] [Tree-iter-order]
+ left Tree-iter-order key [key value left right] [Tree-iter-order]
Process the right child.
~~~~~~~~~~~~~~~~~~~~~~~~
::
- left Tree-iter-order key [key value left right] [Tree-iter-order] [rest rest rest first] dip
- left Tree-iter-order key right [Tree-iter-order]
+ left Tree-iter-order key [key value left right] [Tree-iter-order] [rest rest rest first] dip
+ left Tree-iter-order key right [Tree-iter-order]
Then, of course, we just need ``i`` to run ``Tree-iter-order`` on the
right side:
::
- left Tree-iter-order key right [Tree-iter-order] i
- left Tree-iter-order key right Tree-iter-order
+ left Tree-iter-order key right [Tree-iter-order] i
+ left Tree-iter-order key right Tree-iter-order
Defining ``Tree-iter-order``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- R1 == [cons dip] dupdip [[F] dupdip] dip [rest rest rest first] dip i
+ R1 == [cons dip] dupdip [[F] dupdip] dip [rest rest rest first] dip i
-Let's do a little semantic factoring:
+Let’s do a little semantic factoring:
::
- fourth == rest rest rest first
+ fourth == rest rest rest first
- proc_left == [cons dip] dupdip
- proc_current == [[F] dupdip] dip
- proc_right == [fourth] dip i
+ proc_left == [cons dip] dupdip
+ proc_current == [[F] dupdip] dip
+ proc_right == [fourth] dip i
- Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] genrec
+ Tree-iter-order == [not] [pop] [dup third] [proc_left proc_current proc_right] genrec
Now we can sort sequences.
Getting values by key
---------------------
-Let's derive a function that accepts a tree and a key and returns the
+Let’s derive a function that accepts a tree and a key and returns the
value associated with that key.
::
- tree key Tree-get
- -----------------------
- value
+ tree key Tree-get
+ -----------------------
+ value
-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", I think.)
+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”, I think.)
-Let's pass the buck to the caller by making the base case a given, you
+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] Tree-get
- ---------------------------- key in tree
- value
+ tree key [E] Tree-get
+ ---------------------------- key in tree
+ value
- tree key [E] Tree-get
- ---------------------------- key not in tree
- [] key E
+ tree key [E] Tree-get
+ ---------------------------- key not in tree
+ [] key E
The base case ``[]``
~~~~~~~~~~~~~~~~~~~~
::
- Tree-get == [pop not] [E] [R0] [R1] genrec
+ Tree-get == [pop not] [E] [R0] [R1] genrec
So we define:
::
- Tree-get == [pop not] swap [R0] [R1] genrec
+ Tree-get == [pop not] swap [R0] [R1] genrec
Note that this ``Tree-get`` creates a slightly different function than
itself and *that function* does the actual recursion. This kind of
::
- tree key [E] [pop not] swap [R0] [R1] genrec
- tree key [pop not] [E] [R0] [R1] genrec
+ 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
+ [pop not] [E] [R0] [R1] genrec
Node case ``[key value left right]``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- [key value left right] key R0 [BTree-get] 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, otherwise recur on one of the child
-nodes. So it's very similar to the above funtion, with ``[R0] == []``
+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
+ [key value left right] key [BTree-get] P [T>] [E] [T<] cmp
Predicate
^^^^^^^^^
::
- P == over [get-node-key] nullary
- get-node-key == pop popop first
+ P == over [get-node-key] nullary
+ get-node-key == pop popop first
The only difference is that ``get-node-key`` does one less ``pop``
-because there's no value to discard.
+because there’s no value to discard.
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<
+ [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<
Greater than and less than
^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [key_n value_n left right] key [BTree-get] T>
- ---------------------------------------------------
- right key BTree-get
+ [key_n value_n left right] key [BTree-get] T>
+ ---------------------------------------------------
+ right key BTree-get
And:
::
- [key_n value_n left right] key [BTree-get] T<
- ---------------------------------------------------
- left 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
+ 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
+ [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
Equal keys
^^^^^^^^^^
-Return the node's value:
+Return the node’s value:
::
- [key_n value_n left right] key [BTree-get] E == value_n
+ [key_n value_n left right] key [BTree-get] E == value_n
- E == popop second
+ E == popop second
``Tree-get``
~~~~~~~~~~~~
::
- 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
+ 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
- Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
+ Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
.. code:: ipython2
Tree-delete
-----------
-Now let's write a function that can return a tree datastructure with a
+Now let’s write a function that can return a tree datastructure with a
key, value pair deleted:
::
- tree key Tree-delete
- ---------------------------
- tree
+ tree key Tree-delete
+ ---------------------------
+ tree
If the key is not in tree it just returns the tree unchanged.
::
- Tree-Delete == [pop not] [pop] [R0] [R1] genrec
+ Tree-Delete == [pop not] [pop] [R0] [R1] genrec
Recur
~~~~~
-Now we get to figure out the recursive case. We need the node's key to
+Now we get to figure out the recursive case. We need the node’s key to
compare and we need to carry the key into recursive branches. Let ``D``
be shorthand for ``Tree-Delete``:
::
- D == Tree-Delete == [pop not] [pop] [R0] [R1] genrec
+ D == Tree-Delete == [pop not] [pop] [R0] [R1] genrec
- [node_key node_value left right] key R0 [D] R1
- [node_key node_value left right] key over first swap dup [D] cons R1′
- [node_key node_value left right] key [...] first swap dup [D] cons R1′
- [node_key node_value left right] key node_key swap dup [D] cons R1′
- [node_key node_value left right] node_key key dup [D] cons R1′
- [node_key node_value left right] node_key key key [D] cons R1′
- [node_key node_value left right] node_key key [key D] R1′
+ [node_key node_value left right] key R0 [D] R1
+ [node_key node_value left right] key over first swap dup [D] cons R1′
+ [node_key node_value left right] key [...] first swap dup [D] cons R1′
+ [node_key node_value left right] key node_key swap dup [D] cons R1′
+ [node_key node_value left right] node_key key dup [D] cons R1′
+ [node_key node_value left right] node_key key key [D] cons R1′
+ [node_key node_value left right] node_key key [key D] R1′
And then:
::
- [node_key node_value left right] node_key key [key D] R1′
- [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
- [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
- [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
+ [node_key node_value left right] node_key key [key D] R1′
+ [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
+ [node_key node_value left right] node_key key [key D] roll> [T>] [E] [T<] cmp
+ [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
So:
::
- R0 == over first swap dup
- R1 == cons roll> [T>] [E] [T<] cmp
+ R0 == over first swap dup
+ R1 == cons roll> [T>] [E] [T<] cmp
Compare Keys
~~~~~~~~~~~~
::
- [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
+ [node_key node_value left right] [key D] node_key key [T>] [E] [T<] cmp
Then becomes one of these three:
::
- [node_key node_value left right] [key D] T>
- [node_key node_value left right] [key D] E
- [node_key node_value left right] [key D] T<
+ [node_key node_value left right] [key D] T>
+ [node_key node_value left right] [key D] E
+ [node_key node_value left right] [key D] T<
Greater than case and less than case
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
- [node_key node_value left right] [F] T>
- -------------------------------------------------
- [node_key node_value (left F) right]
+ [node_key node_value left right] [F] T>
+ -------------------------------------------------
+ [node_key node_value (left F) right]
- [node_key node_value left right] [F] T<
- -------------------------------------------------
- [node_key node_value left (right F)]
+ [node_key node_value left right] [F] T<
+ -------------------------------------------------
+ [node_key node_value left (right F)]
First, treating the node as a stack:
::
- right left node_value node_key [key D] dipd
- right left key D node_value node_key
- right left' node_value node_key
+ right left node_value node_key [key D] dipd
+ right left key D node_value node_key
+ right left' node_value node_key
Ergo:
::
- [node_key node_value left right] [key D] [dipd] cons infra
+ [node_key node_value left right] [key D] [dipd] cons infra
So:
::
- T> == [dipd] cons infra
- T< == [dipdd] cons infra
+ T> == [dipd] cons infra
+ T< == [dipdd] cons infra
The else case
~~~~~~~~~~~~~
::
- [node_key node_value left right] [key D] E
- ------------------------------------------------
- tree
+ [node_key node_value left right] [key D] E
+ ------------------------------------------------
+ tree
-We have to handle three cases, so let's use ``cond``.
+We have to handle three cases, so let’s use ``cond``.
One or more child nodes are ``[]``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [default]
- ] cond
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [default]
+ ] cond
Both child nodes are non-empty.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- default == [E′] cons infra
+ default == [E′] cons infra
- [node_key node_value left right] [key D] default
- [node_key node_value left right] [key D] [E′] cons infra
- [node_key node_value left right] [[key D] E′] infra
+ [node_key node_value left right] [key D] default
+ [node_key node_value left right] [key D] [E′] cons infra
+ [node_key node_value left right] [[key D] E′] infra
- right left node_value node_key [key D] E′
+ right left node_value node_key [key D] E′
-First things first, we no longer need this node's key and value:
+First things first, we no longer need this node’s key and value:
::
- right left node_value node_key [key D] roll> popop E″
- right left [key D] node_value node_key popop E″
- right left [key D] E″
+ right left node_value node_key [key D] roll> popop E″
+ right left [key D] node_value node_key popop E″
+ right left [key D] E″
We have to we find the highest (right-most) node in our lower (left) sub-tree:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- right left [key D] E″
+ right left [key D] E″
Ditch the key:
::
- right left [key D] rest E‴
- right left [D] E‴
+ right left [key D] rest E‴
+ right left [D] E‴
Find the right-most node:
::
- right left [D] [dup W] dip E⁗
- right left dup W [D] E⁗
- right left left W [D] E⁗
+ right left [D] [dup W] dip E⁗
+ right left dup W [D] E⁗
+ right left left W [D] E⁗
Consider:
::
- left W
+ left W
We know left is not empty:
::
- [L_key L_value L_left L_right] W
+ [L_key L_value L_left L_right] W
We want to keep extracting the right node as long as it is not empty:
::
- W.rightmost == [P] [B] while
+ W.rightmost == [P] [B] while
- left W.rightmost W′
+ left W.rightmost W′
The predicate:
::
- [L_key L_value L_left L_right] P
- [L_key L_value L_left L_right] fourth
- L_right
+ [L_key L_value L_left L_right] P
+ [L_key L_value L_left L_right] fourth
+ L_right
This can run on ``[]`` so must be guarded:
::
- ?fourth == [] [fourth] [] ifte
+ ?fourth == [] [fourth] [] ifte
-( if\_not\_empty == [] swap [] ifte ?fourth == [fourth] if\_not\_empty )
+( if_not_empty == [] swap [] ifte ?fourth == [fourth] if_not_empty )
The body is just ``fourth``:
::
- left [?fourth] [fourth] while W′
- rightest W′
+ left [?fourth] [fourth] while W′
+ rightest W′
So:
::
- W.rightmost == [?fourth] [fourth] while
+ W.rightmost == [?fourth] [fourth] while
Found right-most node in our left sub-tree
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- [R_key R_value R_left R_right] W′
- [R_key R_value R_left R_right] W′
- [R_key R_value R_left R_right] uncons uncons pop
- R_key [R_value R_left R_right] uncons pop
- R_key R_value [R_left R_right] pop
- R_key R_value
+ [R_key R_value R_left R_right] W′
+ [R_key R_value R_left R_right] W′
+ [R_key R_value R_left R_right] uncons uncons pop
+ R_key [R_value R_left R_right] uncons pop
+ R_key R_value [R_left R_right] pop
+ R_key R_value
So:
::
- W == [?fourth] [fourth] while uncons uncons pop
+ W == [?fourth] [fourth] while uncons uncons pop
And:
::
- right left left W [D] E⁗
- right left R_key R_value [D] E⁗
+ right left left W [D] E⁗
+ right left R_key R_value [D] E⁗
Replace current node key and value, recursively delete rightmost
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
- right left [R_key D] i R_value R_key
- right left R_key D R_value R_key
- right left′ R_value R_key
+ right left [R_key D] i R_value R_key
+ right left R_key D R_value R_key
+ right left′ R_value R_key
If we adjust our definition of ``W`` to include ``over`` at the end:
::
- W == [fourth] [fourth] while uncons uncons pop over
+ W == [fourth] [fourth] while uncons uncons pop over
That will give us:
::
- right left R_key R_value R_key [D] E⁗
+ right left R_key R_value R_key [D] E⁗
- right left R_key R_value R_key [D] cons dipd E⁗′
- right left R_key R_value [R_key D] dipd E⁗′
- right left R_key D R_key R_value E⁗′
- right left′ R_key R_value E⁗′
- right left′ R_key R_value swap
- right left′ R_value R_key
+ right left R_key R_value R_key [D] cons dipd E⁗′
+ right left R_key R_value [R_key D] dipd E⁗′
+ right left R_key D R_key R_value E⁗′
+ right left′ R_key R_value E⁗′
+ right left′ R_key R_value swap
+ right left′ R_value R_key
So:
::
- E′ == roll> popop E″
+ E′ == roll> popop E″
- E″ == rest E‴
+ E″ == rest E‴
- E‴ == [dup W] dip E⁗
+ E‴ == [dup W] dip E⁗
- E⁗ == cons dipdd swap
+ E⁗ == cons dipdd swap
Substituting:
::
- W == [fourth] [fourth] while uncons uncons pop over
- E′ == roll> popop rest [dup W] dip cons dipd swap
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [[E′] cons infra]
- ] cond
+ W == [fourth] [fourth] while uncons uncons pop over
+ E′ == roll> popop rest [dup W] dip cons dipd swap
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [[E′] cons infra]
+ ] cond
Minor rearrangement, move ``dup`` into ``W``:
::
- W == dup [fourth] [fourth] while uncons uncons pop over
- E′ == roll> popop rest [W] dip cons dipd swap
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [[E′] cons infra]
- ] cond
+ W == dup [fourth] [fourth] while uncons uncons pop over
+ E′ == roll> popop rest [W] dip cons dipd swap
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [[E′] cons infra]
+ ] cond
Refactoring
~~~~~~~~~~~
::
- W.rightmost == [fourth] [fourth] while
- W.unpack == uncons uncons pop
- W == dup W.rightmost W.unpack over
- E.clear_stuff == roll> popop rest
- E.delete == cons dipd
- E.0 == E.clear_stuff [W] dip E.delete swap
- E == [
- [[pop third not] pop fourth]
- [[pop fourth not] pop third]
- [[E.0] cons infra]
- ] cond
- T> == [dipd] cons infra
- T< == [dipdd] cons infra
- R0 == over first swap dup
- R1 == cons roll> [T>] [E] [T<] cmp
- BTree-Delete == [pop not] swap [R0] [R1] genrec
-
-By the standards of the code I've written so far, this is a *huge* Joy
+ W.rightmost == [fourth] [fourth] while
+ W.unpack == uncons uncons pop
+ W == dup W.rightmost W.unpack over
+ E.clear_stuff == roll> popop rest
+ E.delete == cons dipd
+ E.0 == E.clear_stuff [W] dip E.delete swap
+ E == [
+ [[pop third not] pop fourth]
+ [[pop fourth not] pop third]
+ [[E.0] cons infra]
+ ] cond
+ T> == [dipd] cons infra
+ T< == [dipdd] cons infra
+ R0 == over first swap dup
+ R1 == cons roll> [T>] [E] [T<] cmp
+ BTree-Delete == [pop not] swap [R0] [R1] genrec
+
+By the standards of the code I’ve written so far, this is a *huge* Joy
program.
.. code:: ipython2
::
- fourth == rest_two rest first
- ?fourth == [] [fourth] [] ifte
- first_two == uncons uncons pop
- ccons == cons cons
- cinf == cons infra
- rest_two == rest rest
-
- _Tree_T> == [dipd] cinf
- _Tree_T< == [dipdd] cinf
-
- _Tree_add_P == over [popop popop first] nullary
- _Tree_add_T> == ccons _Tree_T<
- _Tree_add_T< == ccons _Tree_T>
- _Tree_add_Ee == pop swap roll< rest_two ccons
- _Tree_add_R == _Tree_add_P [_Tree_add_T>] [_Tree_add_Ee] [_Tree_add_T<] cmp
- _Tree_add_E == [pop] dipd Tree-new
-
- _Tree_iter_order_left == [cons dip] dupdip
- _Tree_iter_order_current == [[F] dupdip] dip
- _Tree_iter_order_right == [fourth] dip i
- _Tree_iter_order_R == _Tree_iter_order_left _Tree_iter_order_current _Tree_iter_order_right
-
- _Tree_get_P == over [pop popop first] nullary
- _Tree_get_T> == [fourth] dipd i
- _Tree_get_T< == [third] dipd i
- _Tree_get_E == popop second
- _Tree_get_R == _Tree_get_P [_Tree_get_T>] [_Tree_get_E] [_Tree_get_T<] cmp
-
- _Tree_delete_rightmost == [?fourth] [fourth] while
- _Tree_delete_clear_stuff == roll> popop rest
- _Tree_delete_del == dip cons dipd swap
- _Tree_delete_W == dup _Tree_delete_rightmost first_two over
- _Tree_delete_E.0 == _Tree_delete_clear_stuff [_Tree_delete_W] _Tree_delete_del
- _Tree_delete_E == [[[pop third not] pop fourth] [[pop fourth not] pop third] [[_Tree_delete_E.0] cinf]] cond
- _Tree_delete_R0 == over first swap dup
- _Tree_delete_R1 == cons roll> [_Tree_T>] [_Tree_delete_E] [_Tree_T<] cmp
-
- Tree-new == swap [[] []] ccons
- Tree-add == [popop not] [_Tree_add_E] [] [_Tree_add_R] genrec
- Tree-iter == [not] [pop] roll< [dupdip rest_two] cons [step] genrec
- Tree-iter-order == [not] [pop] [dup third] [_Tree_iter_order_R] genrec
- Tree-get == [pop not] swap [] [_Tree_get_R] genrec
- Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec
+ fourth == rest_two rest first
+ ?fourth == [] [fourth] [] ifte
+ first_two == uncons uncons pop
+ ccons == cons cons
+ cinf == cons infra
+ rest_two == rest rest
+
+ _Tree_T> == [dipd] cinf
+ _Tree_T< == [dipdd] cinf
+
+ _Tree_add_P == over [popop popop first] nullary
+ _Tree_add_T> == ccons _Tree_T<
+ _Tree_add_T< == ccons _Tree_T>
+ _Tree_add_Ee == pop swap roll< rest_two ccons
+ _Tree_add_R == _Tree_add_P [_Tree_add_T>] [_Tree_add_Ee] [_Tree_add_T<] cmp
+ _Tree_add_E == [pop] dipd Tree-new
+
+ _Tree_iter_order_left == [cons dip] dupdip
+ _Tree_iter_order_current == [[F] dupdip] dip
+ _Tree_iter_order_right == [fourth] dip i
+ _Tree_iter_order_R == _Tree_iter_order_left _Tree_iter_order_current _Tree_iter_order_right
+
+ _Tree_get_P == over [pop popop first] nullary
+ _Tree_get_T> == [fourth] dipd i
+ _Tree_get_T< == [third] dipd i
+ _Tree_get_E == popop second
+ _Tree_get_R == _Tree_get_P [_Tree_get_T>] [_Tree_get_E] [_Tree_get_T<] cmp
+
+ _Tree_delete_rightmost == [?fourth] [fourth] while
+ _Tree_delete_clear_stuff == roll> popop rest
+ _Tree_delete_del == dip cons dipd swap
+ _Tree_delete_W == dup _Tree_delete_rightmost first_two over
+ _Tree_delete_E.0 == _Tree_delete_clear_stuff [_Tree_delete_W] _Tree_delete_del
+ _Tree_delete_E == [[[pop third not] pop fourth] [[pop fourth not] pop third] [[_Tree_delete_E.0] cinf]] cond
+ _Tree_delete_R0 == over first swap dup
+ _Tree_delete_R1 == cons roll> [_Tree_T>] [_Tree_delete_E] [_Tree_T<] cmp
+
+ Tree-new == swap [[] []] ccons
+ Tree-add == [popop not] [_Tree_add_E] [] [_Tree_add_R] genrec
+ Tree-iter == [not] [pop] roll< [dupdip rest_two] cons [step] genrec
+ Tree-iter-order == [not] [pop] [dup third] [_Tree_iter_order_R] genrec
+ Tree-get == [pop not] swap [] [_Tree_get_R] genrec
+ Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec
::
- -b ± sqrt(b^2 - 4 * a * c)
- --------------------------------
- 2 * a
+ -b ± sqrt(b^2 - 4 * a * c)
+ --------------------------------
+ 2 * a
:math:`\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}`
::
- b neg
+ b neg
``sqrt(b^2 - 4 * a * c)``
~~~~~~~~~~~~~~~~~~~~~~~~~
::
- b sqr 4 a c * * - sqrt
+ b sqr 4 a c * * - sqrt
``/2a``
~~~~~~~
::
- a 2 * /
+ a 2 * /
``±``
~~~~~
::
- pm == [+] [-] cleave popdd
+ pm == [+] [-] cleave popdd
Putting Them Together
~~~~~~~~~~~~~~~~~~~~~
::
- b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
+ b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
We use ``app2`` to compute both roots by using a quoted program
``[2a /]`` built with ``cons``.
::
- b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
- b [neg] dupdip sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
- b a c [[neg] dupdip sqr 4] dipd * * - sqrt pm a 2 * [/] cons app2
- b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
- b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
+ b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
+ b [neg] dupdip sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
+ b a c [[neg] dupdip sqr 4] dipd * * - sqrt pm a 2 * [/] cons app2
+ b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
+ b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
-The three arguments are to the left, so we can "chop off" everything to
-the right and say it's the definition of the ``quadratic`` function:
+The three arguments are to the left, so we can “chop off” everything to
+the right and say it’s the definition of the ``quadratic`` function:
.. code:: ipython2
define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
-Let's try it out:
+Let’s try it out:
.. code:: ipython2
::
- [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."
+ [if] [then] [rec1] [rec2] genrec
+ ---------------------------------------------------------------------
+ [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
+
+From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun:
+
+ “The genrec combinator takes four program parameters in addition to
+ whatever data parameters it needs. Fourth from the top is an if-part,
+ followed by a then-part. If the if-part yields true, then the
+ then-part is executed and the combinator terminates. The other two
+ parameters are the rec1-part and the rec2-part. If the if-part yields
+ false, the rec1-part is executed. Following that the four program
+ parameters and the combinator are again pushed onto the stack bundled
+ up in a quoted form. Then the rec2-part is executed, where it will
+ find the bundled form. Typically it will then execute the bundled
+ form, either with i or with app2, or some other combinator.”
Designing Recursive Functions
-----------------------------
The way to design one of these is to fix your base case and test and
-then treat ``R1`` and ``R2`` as an else-part "sandwiching" a quotation
+then treat ``R1`` and ``R2`` as an else-part “sandwiching” a quotation
of the whole function.
For example, given a (general recursive) function ``F``:
::
- F == [I] [T] [R1] [R2] genrec
- == [I] [T] [R1 [F] R2] ifte
+ F == [I] [T] [R1] [R2] genrec
+ == [I] [T] [R1 [F] R2] ifte
If the ``[I]`` predicate is false you must derive ``R1`` and ``R2``
from:
::
- ... R1 [F] R2
+ ... R1 [F] R2
Set the stack arguments in front and figure out what ``R1`` and ``R2``
have to do to apply the quoted ``[F]`` in the proper way.
::
- P == [I] [T] [R] primrec
- == [I] [T] [R [P] i] ifte
- == [I] [T] [R P] ifte
+ P == [I] [T] [R] primrec
+ == [I] [T] [R [P] i] ifte
+ == [I] [T] [R P] ifte
`Hylomorphism <https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29>`__
------------------------------------------------------------------------------------
- A combiner ``F :: (B, C) -> C``
- A predicate ``P :: A -> Bool`` to detect the base case
- A base case value ``c :: C``
-- Recursive calls (zero or more); it has a "call stack in the form of a
- cons list".
+- 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.
return H
-Cf. `"Bananas, Lenses, & Barbed
-Wire" <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
+Cf. `“Bananas, Lenses, & Barbed
+Wire” <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
Note that during evaluation of ``H()`` the intermediate ``b`` values are
-stored in the Python call stack. This is what is meant by "call stack in
-the form of a cons list".
+stored in the Python call stack. This is what is meant by “call stack in
+the form of a cons list”.
Hylomorphism in Joy
-------------------
::
- H == [P] c [G] [F] hylomorphism
+ H == [P] c [G] [F] hylomorphism
The function ``H`` is recursive, so we start with ``ifte`` and set the
else-part to some function ``J`` that will contain a quoted copy of
::
- H == [P] [pop c] [J] ifte
+ 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.
+ 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
+ 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
+ H == [P] [pop c] [G [H] dip F] ifte
+ H == [P] [pop c] [G] [dip F] genrec
This is the form of a hylomorphism in Joy, which nicely illustrates that
it is a simple specialization of the general recursion combinator.
::
- H == [P] c [G] [F] hylomorphism == [P] [pop c] [G] [dip F] genrec
+ H == [P] c [G] [F] hylomorphism == [P] [pop c] [G] [dip F] genrec
Derivation of ``hylomorphism`` combinator
-----------------------------------------
::
- [P] c [G] [F] hylomorphism
- ------------------------------------------
- [P] [pop c] [G] [dip F] genrec
+ [P] c [G] [F] hylomorphism
+ ------------------------------------------
+ [P] [pop c] [G] [dip F] genrec
Working in reverse:
::
- 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
+ H == [P] [pop c] [G] [dip F] genrec
+ [P] [c] [pop] swoncat [G] [F] [dip] swoncat genrec
+ [P] c unit [pop] swoncat [G] [F] [dip] swoncat genrec
+ [P] c [G] [F] [unit [pop] swoncat] dipd [dip] swoncat genrec
At this point all of the arguments (givens) to the hylomorphism are to
the left so we have a definition for ``hylomorphism``:
::
- hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
+ hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
.. code:: ipython2
Example: Finding `Triangular Numbers <https://en.wikipedia.org/wiki/Triangular_number>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Let's write a function that, given a positive integer, returns the sum
+Let’s write a function that, given a positive integer, returns the sum
of all positive integers less than that one. (In this case the types
``A``, ``B`` and ``C`` are all ``int``.)
define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')
-Let's try it:
+Let’s try it:
.. code:: ipython2
There are at least four kinds of recursive combinator, depending on two
choices. The first choice is whether the combiner function ``F`` should
be evaluated during the recursion or pushed into the pending expression
-to be "collapsed" at the end. The second choice is whether the combiner
+to be “collapsed” at the end. The second choice is whether the combiner
needs to operate on the current value of the datastructure or the
-generator's output, in other words, whether ``F`` or ``G`` should run
+generator’s output, in other words, whether ``F`` or ``G`` should run
first in the recursive branch.
::
- H1 == [P] [pop c] [G ] [dip F] genrec
- H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
- H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
- H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
+ H1 == [P] [pop c] [G ] [dip F] genrec
+ H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
+ H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
+ H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
The working of the generator function ``G`` differs slightly for each.
Consider the recursive branches:
::
- ... a G [H1] dip F w/ a G == a′ b
+ ... a G [H1] dip F w/ a G == a′ b
- ... c a G [F] dip H2 a G == b a′
+ ... c a G [F] dip H2 a G == b a′
- ... a [G] dupdip [H3] dip F a G == a′
+ ... a [G] dupdip [H3] dip F a G == a′
- ... c a [F] dupdip G H4 a G == a′
+ ... c a [F] dupdip G H4 a G == a′
The following four sections illustrate how these work, omitting the
predicate evaluation.
::
- H1 == [P] [pop c] [G] [dip F] genrec
+ H1 == [P] [pop c] [G] [dip F] genrec
Iterate n times.
::
- ... a G [H1] dip F
- ... a′ b [H1] dip F
- ... a′ H1 b F
- ... a′ G [H1] dip F b F
- ... a″ b′ [H1] dip F b F
- ... a″ H1 b′ F b F
- ... a″ G [H1] dip F b′ F b F
- ... a‴ b″ [H1] dip F b′ F b F
- ... a‴ H1 b″ F b′ F b F
- ... a‴ pop c b″ F b′ F b F
- ... c b″ F b′ F b F
- ... d b′ F b F
- ... d′ b F
- ... d″
+ ... a G [H1] dip F
+ ... a′ b [H1] dip F
+ ... a′ H1 b F
+ ... a′ G [H1] dip F b F
+ ... a″ b′ [H1] dip F b F
+ ... a″ H1 b′ F b F
+ ... a″ G [H1] dip F b′ F b F
+ ... a‴ b″ [H1] dip F b′ F b F
+ ... a‴ H1 b″ F b′ F b F
+ ... a‴ pop c b″ F b′ F b F
+ ... c b″ F b′ F b F
+ ... d b′ F b F
+ ... d′ b F
+ ... d″
This form builds up a pending expression (continuation) that contains
the intermediate results along with the pending combiner functions. When
the base case is reached the last term is replaced by the identity value
-``c`` and the continuation "collapses" into the final result using the
+``c`` and the continuation “collapses” into the final result using the
combiner ``F``.
``H2``
::
- H2 == c swap [P] [pop] [G [F] dip] primrec
+ H2 == c swap [P] [pop] [G [F] dip] primrec
- ... c a G [F] dip H2
- ... c b a′ [F] dip H2
- ... c b F a′ H2
- ... d a′ H2
- ... d a′ G [F] dip H2
- ... d b′ a″ [F] dip H2
- ... d b′ F a″ H2
- ... d′ a″ H2
- ... d′ a″ G [F] dip H2
- ... d′ b″ a‴ [F] dip H2
- ... d′ b″ F a‴ H2
- ... d″ a‴ H2
- ... d″ a‴ pop
- ... d″
+ ... c a G [F] dip H2
+ ... c b a′ [F] dip H2
+ ... c b F a′ H2
+ ... d a′ H2
+ ... d a′ G [F] dip H2
+ ... d b′ a″ [F] dip H2
+ ... d b′ F a″ H2
+ ... d′ a″ H2
+ ... d′ a″ G [F] dip H2
+ ... d′ b″ a‴ [F] dip H2
+ ... d′ b″ F a‴ H2
+ ... d″ a‴ H2
+ ... d″ a‴ pop
+ ... d″
``H3``
~~~~~~
-If you examine the traces above you'll see that the combiner ``F`` only
-gets to operate on the results of ``G``, it never "sees" the first value
+If you examine the traces above you’ll see that the combiner ``F`` only
+gets to operate on the results of ``G``, it never “sees” the first value
``a``. If the combiner and the generator both need to work on the
current value then ``dup`` must be used, and the generator must produce
one item instead of two (the b is instead the duplicate of a.)
::
- H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
+ H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
- ... a [G] dupdip [H3] dip F
- ... a G a [H3] dip F
- ... a′ a [H3] dip F
- ... a′ H3 a F
- ... a′ [G] dupdip [H3] dip F a F
- ... a′ G a′ [H3] dip F a F
- ... a″ a′ [H3] dip F a F
- ... a″ H3 a′ F a F
- ... a″ [G] dupdip [H3] dip F a′ F a F
- ... a″ G a″ [H3] dip F a′ F a F
- ... a‴ a″ [H3] dip F a′ F a F
- ... a‴ H3 a″ F a′ F a F
- ... a‴ pop c a″ F a′ F a F
- ... c a″ F a′ F a F
- ... d a′ F a F
- ... d′ a F
- ... d″
+ ... a [G] dupdip [H3] dip F
+ ... a G a [H3] dip F
+ ... a′ a [H3] dip F
+ ... a′ H3 a F
+ ... a′ [G] dupdip [H3] dip F a F
+ ... a′ G a′ [H3] dip F a F
+ ... a″ a′ [H3] dip F a F
+ ... a″ H3 a′ F a F
+ ... a″ [G] dupdip [H3] dip F a′ F a F
+ ... a″ G a″ [H3] dip F a′ F a F
+ ... a‴ a″ [H3] dip F a′ F a F
+ ... a‴ H3 a″ F a′ F a F
+ ... a‴ pop c a″ F a′ F a F
+ ... c a″ F a′ F a F
+ ... d a′ F a F
+ ... d′ a F
+ ... d″
``H4``
~~~~~~
::
- H4 == c swap [P] [pop] [[F] dupdip G] primrec
+ H4 == c swap [P] [pop] [[F] dupdip G] primrec
- ... c a [F] dupdip G H4
- ... c a F a G H4
- ... d a G H4
- ... d a′ H4
- ... d a′ [F] dupdip G H4
- ... d a′ F a′ G H4
- ... d′ a′ G H4
- ... d′ a″ H4
- ... d′ a″ [F] dupdip G H4
- ... d′ a″ F a″ G H4
- ... d″ a″ G H4
- ... d″ a‴ H4
- ... d″ a‴ pop
- ... d″
+ ... c a [F] dupdip G H4
+ ... c a F a G H4
+ ... d a G H4
+ ... d a′ H4
+ ... d a′ [F] dupdip G H4
+ ... d a′ F a′ G H4
+ ... d′ a′ G H4
+ ... d′ a″ H4
+ ... d′ a″ [F] dupdip G H4
+ ... d′ a″ F a″ G H4
+ ... d″ a″ G H4
+ ... d″ a‴ H4
+ ... d″ a‴ pop
+ ... d″
Anamorphism
-----------
::
- A == [P] [] [G] [swons] hylomorphism
+ A == [P] [] [G] [swons] hylomorphism
-``range`` et. al.
-~~~~~~~~~~~~~~~~~
-
-An example of an anamorphism is the ``range`` function which generates
-the list of integers from 0 to *n* - 1 given *n*.
+``range`` et. al. An example of an anamorphism is the ``range`` function which generates the list of integers from 0 to *n* - 1 given *n*.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Each of the above variations can be used to make four slightly different
``range`` functions.
::
- H1 == [P] [pop c] [G] [dip F] genrec
- == [0 <=] [pop []] [-- dup] [dip swons] genrec
+ H1 == [P] [pop c] [G] [dip F] genrec
+ == [0 <=] [pop []] [-- dup] [dip swons] genrec
.. code:: ipython2
::
- H2 == c swap [P] [pop] [G [F] dip] primrec
- == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
+ H2 == c swap [P] [pop] [G [F] dip] primrec
+ == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
.. code:: ipython2
::
- H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
- == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
+ H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
+ == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
.. code:: ipython2
::
- H4 == c swap [P] [pop] [[F] dupdip G ] primrec
- == [] swap [0 <=] [pop] [[swons] dupdip --] primrec
+ H4 == c swap [P] [pop] [[F] dupdip G ] primrec
+ == [] swap [0 <=] [pop] [[swons] dupdip --] primrec
.. code:: ipython2
::
- C == [not] c [uncons swap] [F] hylomorphism
+ C == [not] c [uncons swap] [F] hylomorphism
.. code:: ipython2
::
- sum == [not] 0 [swuncons] [+] hylomorphism
+ sum == [not] 0 [swuncons] [+] hylomorphism
.. code:: ipython2
::
- H4 == c swap [P] [pop] [[F] dupdip G] primrec
+ H4 == c swap [P] [pop] [[F] dupdip G] primrec
With:
::
- c == 1
- F == *
- G == --
- P == 1 <=
+ c == 1
+ F == *
+ G == --
+ P == 1 <=
.. code:: ipython2
Example: ``tails``
------------------
-An example of a paramorphism for lists given in the `"Bananas..."
+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.
+is ``tails`` which returns the list of “tails” of a list.
::
- [1 2 3] tails
- --------------------
- [[] [3] [2 3]]
+ [1 2 3] tails
+ --------------------
+ [[] [3] [2 3]]
We can build as we go, and we want ``F`` to run after ``G``, so we use
pattern ``H2``:
::
- H2 == c swap [P] [pop] [G [F] dip] primrec
+ H2 == c swap [P] [pop] [G [F] dip] primrec
We would use:
::
- c == []
- F == swons
- G == rest dup
- P == not
+ c == []
+ F == swons
+ G == rest dup
+ P == not
.. code:: ipython2
Conclusion: Patterns of Recursion
---------------------------------
-Our story so far...
+Our story so far…
Hylo-, Ana-, Cata-
~~~~~~~~~~~~~~~~~~
::
- H == [P ] [pop c ] [G ] [dip F ] genrec
- A == [P ] [pop []] [G ] [dip swap cons] genrec
- C == [not] [pop c ] [uncons swap] [dip F ] genrec
+ H == [P ] [pop c ] [G ] [dip F ] genrec
+ A == [P ] [pop []] [G ] [dip swap cons] genrec
+ C == [not] [pop c ] [uncons swap] [dip F ] genrec
Para-, ?-, ?-
~~~~~~~~~~~~~
::
- P == c swap [P ] [pop] [[F ] dupdip G ] primrec
- ? == [] swap [P ] [pop] [[swap cons] dupdip G ] primrec
- ? == c swap [not] [pop] [[F ] dupdip uncons swap] primrec
+ P == c swap [P ] [pop] [[F ] dupdip G ] primrec
+ ? == [] swap [P ] [pop] [[swap cons] dupdip G ] primrec
+ ? == c swap [not] [pop] [[F ] dupdip uncons swap] primrec
Appendix: Fun with Symbols
--------------------------
::
- |[ (c, F), (G, P) ]| == (|c, F|) • [(G, P)]
+ |[ (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>`__
+`“Bananas, Lenses, & Barbed
+Wire” <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125>`__
::
- (|...|) [(...)] [<...>]
+ (|...|) [(...)] [<...>]
I think they are having slightly too much fun with the symbols. However,
-"Too much is always better than not enough."
+“Too much is always better than not enough.”
For now, there is no way to define new functions from within the Joy
language. All functions (and the interpreter) all accept and return a
dictionary parameter (in addition to the stack and expression) so that
-we can implement e.g. a function that adds new functions to the
-dictionary. However, there's no function that does that. Adding a new
+we can implement e.g. a function that adds new functions to the
+dictionary. However, there’s no function that does that. Adding a new
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.
::
- sum == 0 swap [+] step
- size == 0 swap [pop ++] step
+ sum == 0 swap [+] step
+ size == 0 swap [pop ++] step
An efficient ``sum`` function is already in the library. But for
``size`` we can use a “compiled” version hand-written in Python to speed
::
- foo bar
+ foo bar
Operations have inputs and outputs. The outputs of ``foo`` must be
-compatible in "arity", type, and shape with the inputs of ``bar``.
+compatible in “arity”, type, and shape with the inputs of ``bar``.
Branch
------
::
- boolean [F] [T] branch
+ boolean [F] [T] branch
- t [F] [T] branch
- ----------------------
- T
+ t [F] [T] branch
+ ----------------------
+ T
- f [F] [T] branch
- ----------------------
- F
+ f [F] [T] branch
+ ----------------------
+ F
- branch == unit cons swap pick i
+ branch == unit cons swap pick i
- boolean [F] [T] branch
- boolean [F] [T] unit cons swap pick i
- boolean [F] [[T]] cons swap pick i
- boolean [[F] [T]] swap pick i
- [[F] [T]] boolean pick i
- [F-or-T] i
+ boolean [F] [T] branch
+ boolean [F] [T] unit cons swap pick i
+ boolean [F] [[T]] cons swap pick i
+ boolean [[F] [T]] swap pick i
+ [[F] [T]] boolean pick i
+ [F-or-T] i
Given some branch function ``G``:
::
- G == [F] [T] branch
+ G == [F] [T] branch
Used in a sequence like so:
::
- foo G bar
+ foo G bar
The inputs and outputs of ``F`` and ``T`` must be compatible with the
outputs for ``foo`` and the inputs of ``bar``, respectively.
::
- foo F bar
+ foo F bar
- foo T bar
+ foo T bar
``ifte``
~~~~~~~~
Often it will be easier on the programmer to write branching code with
the predicate specified in a quote. The ``ifte`` combinator provides
-this (``T`` for "then" and ``E`` for "else"):
+this (``T`` for “then” and ``E`` for “else”):
::
- [P] [T] [E] ifte
+ [P] [T] [E] ifte
Defined in terms of ``branch``:
::
- ifte == [nullary not] dip branch
+ ifte == [nullary not] dip branch
In this case, ``P`` must be compatible with the stack and return a
Boolean value, and ``T`` and ``E`` both must be compatible with the
preceeding and following functions, as described above for ``F`` and
``T``. (Note that in the current implementation we are depending on
-Python for the underlying semantics, so the Boolean value doesn't *have*
-to be Boolean because Python's rules for "truthiness" will be used to
+Python for the underlying semantics, so the Boolean value doesn’t *have*
+to be Boolean because Python’s rules for “truthiness” will be used to
evaluate it. I reflect this in the structure of the stack effect comment
of ``branch``, it will only accept Boolean values, and in the definition
of ``ifte`` above by including ``not`` in the quote, which also has the
::
- boolean [Q] loop
+ boolean [Q] loop
- t [Q] loop
- ----------------
- Q [Q] loop
+ t [Q] loop
+ ----------------
+ Q [Q] loop
- ... f [Q] loop
- --------------------
- ...
+ ... f [Q] loop
+ --------------------
+ ...
The ``loop`` combinator generates a copy of itself in the true branch.
This is the hallmark of recursive defintions. In Thun there is no
::
- loop == [] swap [dup dip loop] cons branch
+ loop == [] swap [dup dip loop] cons branch
- boolean [Q] loop
- boolean [Q] [] swap [dup dip loop] cons branch
- boolean [] [Q] [dup dip loop] cons branch
- boolean [] [[Q] dup dip loop] branch
+ boolean [Q] loop
+ boolean [Q] [] swap [dup dip loop] cons branch
+ boolean [] [Q] [dup dip loop] cons branch
+ boolean [] [[Q] dup dip loop] branch
In action the false branch does nothing while the true branch does:
::
- t [] [[Q] dup dip loop] branch
- [Q] dup dip loop
- [Q] [Q] dip loop
- Q [Q] loop
+ t [] [[Q] dup dip loop] branch
+ [Q] dup dip loop
+ [Q] [Q] dip loop
+ Q [Q] loop
Because ``loop`` expects and consumes a Boolean value, the ``Q``
function must be compatible with the previous stack *and itself* with a
::
- Q == G b
+ Q == G b
- Q [Q] loop
- G b [Q] loop
- G Q [Q] loop
- G G b [Q] loop
- G G Q [Q] loop
- G G G b [Q] loop
- G G G
+ Q [Q] loop
+ G b [Q] loop
+ G Q [Q] loop
+ G G b [Q] loop
+ G G Q [Q] loop
+ G G G b [Q] loop
+ G G G
``while``
~~~~~~~~~
::
- [P] [B] while
- --------------------------------------
- [P] nullary [B [P] nullary] loop
+ [P] [B] while
+ --------------------------------------
+ [P] nullary [B [P] nullary] loop
- while == swap [nullary] cons dup dipd concat loop
+ while == swap [nullary] cons dup dipd concat loop
- [P] [B] while
- [P] [B] swap [nullary] cons dup dipd concat loop
- [B] [P] [nullary] cons dup dipd concat loop
- [B] [[P] nullary] dup dipd concat loop
- [B] [[P] nullary] [[P] nullary] dipd concat loop
- [P] nullary [B] [[P] nullary] concat loop
- [P] nullary [B [P] nullary] loop
+ [P] [B] while
+ [P] [B] swap [nullary] cons dup dipd concat loop
+ [B] [P] [nullary] cons dup dipd concat loop
+ [B] [[P] nullary] dup dipd concat loop
+ [B] [[P] nullary] [[P] nullary] dipd concat loop
+ [P] nullary [B] [[P] nullary] concat loop
+ [P] nullary [B [P] nullary] loop
Parallel
--------
The *parallel* operation indicates that two (or more) functions *do not
interfere* with each other and so can run in parallel. The main
difficulty in this sort of thing is orchestrating the recombining
-("join" or "wait") of the results of the functions after they finish.
+(“join” or “wait”) of the results of the functions after they finish.
The current implementaions and the following definitions *are not
-actually parallel* (yet), but there is no reason they couldn't be
-reimplemented in terms of e.g. Python threads. I am not concerned with
+actually parallel* (yet), but there is no reason they couldn’t be
+reimplemented in terms of e.g. Python threads. I am not concerned with
performance of the system just yet, only the elegance of the code it
allows us to write.
::
- ... x [A] [B] cleave
- ---------------------------------------------------------
- ... [x ...] [A] infra first [x ...] [B] infra first
- ---------------------------------------------------------
- ... a b
+ ... x [A] [B] cleave
+ ---------------------------------------------------------
+ ... [x ...] [A] infra first [x ...] [B] infra first
+ ---------------------------------------------------------
+ ... a b
The ``cleave`` combinator expects a value and two quotes and it executes
-each quote in "separate universes" such that neither can affect the
+each quote in “separate universes” such that neither can affect the
other, then it takes the first item from the stack in each universe and
replaces the value and quotes with their respective results.
-(I think this corresponds to the "fork" operator, the little
+(I think this corresponds to the “fork” operator, the little
upward-pointed triangle, that takes two functions ``A :: x -> a`` and
``B :: x -> b`` and returns a function ``F :: x -> (a, b)``, in Conal
-Elliott's "Compiling to Categories" paper, et. al.)
+Elliott’s “Compiling to Categories” paper, et. al.)
Just a thought, if you ``cleave`` two jobs and one requires more time to
-finish than the other you'd like to be able to assign resources
+finish than the other you’d like to be able to assign resources
accordingly so that they both finish at the same time.
-"Apply" Functions
+“Apply” Functions
~~~~~~~~~~~~~~~~~
There are also ``app2`` and ``app3`` which run a single quote on more
::
- ... y x [Q] app2
- ---------------------------------------------------------
- ... [y ...] [Q] infra first [x ...] [Q] infra first
+ ... y x [Q] app2
+ ---------------------------------------------------------
+ ... [y ...] [Q] infra first [x ...] [Q] infra first
- ... z y x [Q] app3
- ---------------------------------
- ... [z ...] [Q] infra first
- [y ...] [Q] infra first
- [x ...] [Q] infra first
+ ... z y x [Q] app3
+ ---------------------------------
+ ... [z ...] [Q] infra first
+ [y ...] [Q] infra first
+ [x ...] [Q] infra first
Because the quoted program can be ``i`` we can define ``cleave`` in
terms of ``app2``:
::
- cleave == [i] app2 [popd] dip
+ cleave == [i] app2 [popd] dip
-(I'm not sure why ``cleave`` was specified to take that value, I may
+(I’m not sure why ``cleave`` was specified to take that value, I may
make a combinator that does the same thing but without expecting a
value.)
::
- clv == [i] app2
+ clv == [i] app2
- [A] [B] clv
- ------------------
- a b
+ [A] [B] clv
+ ------------------
+ a b
``map``
~~~~~~~
::
- [a b c ...] [Q] map
+ [a b c ...] [Q] map
-There is no reason why the implementation of ``map`` couldn't distribute
-the ``Q`` function over e.g. a pool of worker CPUs.
+There is no reason why the implementation of ``map`` couldn’t distribute
+the ``Q`` function over e.g. a pool of worker CPUs.
``pam``
~~~~~~~
::
- pam == [i] map
+ pam == [i] map
This can be used to run any number of programs separately on the current
stack and combine their (first) outputs in a result list.
::
- [[A] [B] [C] ...] [i] map
- -------------------------------
- [ a b c ...]
+ [[A] [B] [C] ...] [i] map
+ -------------------------------
+ [ a b c ...]
Handling Other Kinds of Join
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``cleave`` operators and others all have pretty brutal join
semantics: everything works and we always wait for every
sub-computation. We can imagine a few different potentially useful
-patterns of "joining" results from parallel combinators.
+patterns of “joining” results from parallel combinators.
first-to-finish
^^^^^^^^^^^^^^^
The other sub-programs would be cancelled.
-"Fulminators"
+“Fulminators”
^^^^^^^^^^^^^
-Also known as "Futures" or "Promises" (by *everybody* else. "Fulinators"
+Also known as “Futures” or “Promises” (by *everybody* else. “Fulinators”
is what I was going to call them when I was thinking about implementing
them in Thun.)
-The runtime could be amended to permit "thunks" representing the results
+The runtime could be amended to permit “thunks” representing the results
of in-progress computations to be left on the stack and picked up by
subsequent functions. These would themselves be able to leave behind
-more "thunks", the values of which depend on the eventual resolution of
+more “thunks”, the values of which depend on the eventual resolution of
the values of the previous thunks.
-In this way you can create "chains" (and more complex shapes) out of
+In this way you can create “chains” (and more complex shapes) out of
normal-looking code that consist of a kind of call-graph interspersed
-with "asyncronous" ... events?
+with “asyncronous” … events?
In any case, until I can find a rigorous theory that shows that this
-sort of thing works perfectly in Joy code I'm not going to worry about
+sort of thing works perfectly in Joy code I’m not going to worry about
it. (And I think the Categories can deal with it anyhow? Incremental
evaluation, yeah?)
Treating Trees II: ``treestep``
===============================
-Let's consider a tree structure, similar to one described `"Why
-functional programming matters" by John
+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 followed by zero or more child trees. (The
asterisk is meant to indicate the `Kleene
::
- tree = [] | [node tree*]
+ tree = [] | [node tree*]
In the spirit of ``step`` we are going to define a combinator
``treestep`` which expects a tree and three additional items: a
::
- tree [B] [N] [C] treestep
+ tree [B] [N] [C] treestep
If the current tree node is empty then just execute ``B``:
::
- [] [B] [N] [C] treestep
- ---------------------------
- [] B
+ [] [B] [N] [C] treestep
+ ---------------------------
+ [] B
Otherwise, evaluate ``N`` on the node value, ``map`` the whole function
(abbreviated here as ``K``) over the child trees recursively, and then
::
- [node tree*] [B] [N] [C] treestep
- --------------------------------------- w/ K == [B] [N] [C] treestep
- node N [tree*] [K] map C
+ [node tree*] [B] [N] [C] treestep
+ --------------------------------------- w/ K == [B] [N] [C] treestep
+ node N [tree*] [K] map C
-(Later on we'll experiment with making ``map`` part of ``C`` so you can
+(Later on we’ll experiment with making ``map`` part of ``C`` so you can
use other combinators.)
Derive the recursive function.
::
- K == [not] [B] [R0] [R1] genrec
- == [not] [B] [R0 [K] R1] ifte
+ K == [not] [B] [R0] [R1] genrec
+ == [not] [B] [R0 [K] R1] ifte
So we just have to derive ``J``:
::
- J == R0 [K] R1
+ J == R0 [K] R1
The behavior of ``J`` is to accept a (non-empty) tree node and arrive at
the desired outcome.
::
- [node tree*] J
- ------------------------------
- node N [tree*] [K] map C
+ [node tree*] J
+ ------------------------------
+ node N [tree*] [K] map C
So ``J`` will have some form like:
::
- J == ... [N] ... [K] ... [C] ...
+ J == ... [N] ... [K] ... [C] ...
-Let's dive in. First, unquote the node and ``dip`` ``N``.
+Let’s dive in. First, unquote the node and ``dip`` ``N``.
::
- [node tree*] uncons [N] dip
- node [tree*] [N] dip
- node N [tree*]
+ [node tree*] uncons [N] dip
+ node [tree*] [N] dip
+ node N [tree*]
Next, ``map`` ``K`` over the child trees and combine with ``C``.
::
- node N [tree*] [K] map C
- node N [tree*] [K] map C
- node N [K.tree*] C
+ node N [tree*] [K] map C
+ node N [tree*] [K] map C
+ node N [K.tree*] C
So:
::
- J == uncons [N] dip [K] map C
+ J == uncons [N] dip [K] map C
Plug it in and convert to ``genrec``:
::
- K == [not] [B] [J ] ifte
- == [not] [B] [uncons [N] dip [K] map C] ifte
- == [not] [B] [uncons [N] dip] [map C] genrec
+ K == [not] [B] [J ] ifte
+ == [not] [B] [uncons [N] dip [K] map C] ifte
+ == [not] [B] [uncons [N] dip] [map C] genrec
Extract the givens to parameterize the program.
-----------------------------------------------
::
- [not] [B] [uncons [N] dip] [map C] genrec
- [B] [not] swap [uncons [N] dip] [map C] genrec
- [B] [uncons [N] dip] [[not] swap] dip [map C] genrec
- ^^^^^^^^^^^^^^^^
- [B] [[N] dip] [uncons] swoncat [[not] swap] dip [map C] genrec
- [B] [N] [dip] cons [uncons] swoncat [[not] swap] dip [map C] genrec
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ [not] [B] [uncons [N] dip] [map C] genrec
+ [B] [not] swap [uncons [N] dip] [map C] genrec
+ [B] [uncons [N] dip] [[not] swap] dip [map C] genrec
+ ^^^^^^^^^^^^^^^^
+ [B] [[N] dip] [uncons] swoncat [[not] swap] dip [map C] genrec
+ [B] [N] [dip] cons [uncons] swoncat [[not] swap] dip [map C] genrec
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Extract a couple of auxiliary definitions:
::
- TS.0 == [[not] swap] dip
- TS.1 == [dip] cons [uncons] swoncat
+ TS.0 == [[not] swap] dip
+ TS.1 == [dip] cons [uncons] swoncat
::
- [B] [N] TS.1 TS.0 [map C] genrec
- [B] [N] [map C] [TS.1 TS.0] dip genrec
- [B] [N] [C] [map] swoncat [TS.1 TS.0] dip genrec
+ [B] [N] TS.1 TS.0 [map C] genrec
+ [B] [N] [map C] [TS.1 TS.0] dip genrec
+ [B] [N] [C] [map] swoncat [TS.1 TS.0] dip genrec
The givens are all to the left so we have our definition.
::
- [not] [B] [uncons [N] dip] [map C] genrec
- [not] [B] [N] [dip] cons [uncons] swoncat [map C] genrec
- [B] [N] [not] roll> [dip] cons [uncons] swoncat [map C] genrec
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ [not] [B] [uncons [N] dip] [map C] genrec
+ [not] [B] [N] [dip] cons [uncons] swoncat [map C] genrec
+ [B] [N] [not] roll> [dip] cons [uncons] swoncat [map C] genrec
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Define ``treestep``
-------------------
::
- sumtree == [pop 0] [] [sum +] treestep
+ sumtree == [pop 0] [] [sum +] treestep
.. code:: ipython2
::
- [] [pop 0] [] [sum +] treestep
- ------------------------------------
- 0
+ [] [pop 0] [] [sum +] treestep
+ ------------------------------------
+ 0
.. code:: ipython2
::
- [n tree*] [pop 0] [] [sum +] treestep
- n [tree*] [[pop 0] [] [sum +] treestep] map sum +
- n [ ... ] sum +
- n m +
- n+m
+ [n tree*] [pop 0] [] [sum +] treestep
+ n [tree*] [[pop 0] [] [sum +] treestep] map sum +
+ n [ ... ] sum +
+ n m +
+ n+m
.. code:: ipython2
::
- Tree = [] | [[key value] left right]
+ Tree = [] | [[key value] left right]
What kind of functions can we write for this with our ``treestep``?
::
- node N [tree*] [K] map C
+ node N [tree*] [K] map C
Plugging in our BTree structure:
::
- [key value] N [left right] [K] map C
+ [key value] N [left right] [K] map C
Traversal
~~~~~~~~~
::
- [key value] first [left right] [K] map i
- key [value] [left right] [K] map i
- key [left right] [K] map i
- key [lkey rkey ] i
- key lkey rkey
+ [key value] first [left right] [K] map i
+ key [value] [left right] [K] map i
+ key [left right] [K] map i
+ key [lkey rkey ] i
+ key lkey rkey
-This doesn't quite work:
+This doesn’t quite work:
.. code:: ipython2
3 'B' 'B'
-Doesn't work because ``map`` extracts the ``first`` item of whatever its
+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] 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 ]
+ [key value] first [left right] [K] map flatten cons
+ key [left right] [K] map flatten cons
+ key [[lk] [rk] ] flatten cons
+ key [ lk rk ] cons
+ [key lk rk ]
So:
::
- [] [first] [flatten cons] treestep
+ [] [first] [flatten cons] treestep
.. code:: ipython2
::
- key [[lk] [rk]] C
- key [[lk] [rk]] i
- key [lk] [rk] roll<
- [lk] [rk] key swons concat
- [lk] [key rk] concat
- [lk key rk]
+ 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
+ [] [i roll< swons concat] [first] treestep
.. code:: ipython2
With ``treegrind``?
-------------------
-The ``treegrind`` function doesn't include the ``map`` combinator, so
+The ``treegrind`` function doesn’t include the ``map`` combinator, so
the ``[C]`` function must arrange to use some combinator on the quoted
recursive copy ``[K]``. With this function, the pattern for processing a
non-empty node is:
::
- node N [tree*] [K] C
+ node N [tree*] [K] C
Plugging in our BTree structure:
::
- [key value] N [left right] [K] C
+ [key value] N [left right] [K] C
.. code:: ipython2
[3 0] 'N' [2 0] 'N' [9 0] 'N' [5 0] 'N' [4 0] 'N' [8 0] 'N' [6 0] 'N' [7 0] 'N'
-Sum the nodes' keys.
+Sum the nodes’ keys.
.. code:: ipython2
::
- [B] [N] [C] treegrind
+ [B] [N] [C] treegrind
-We'll start by saying that the base-case (the key is not in the tree) is
+We’ll start by saying that the base-case (the key is not in the tree) is
user defined, and the per-node function is just the query key literal:
::
- [B] [query_key] [C] treegrind
+ [B] [query_key] [C] treegrind
This means we just have to define ``C`` from:
::
- [key value] query_key [left right] [K] C
+ [key value] query_key [left right] [K] C
-Let's try ``cmp``:
+Let’s try ``cmp``:
::
- C == P [T>] [E] [T<] cmp
+ C == P [T>] [E] [T<] cmp
- [key value] query_key [left right] [K] P [T>] [E] [T<] cmp
+ [key value] query_key [left right] [K] P [T>] [E] [T<] cmp
The predicate ``P``
~~~~~~~~~~~~~~~~~~~
::
- [key value] query_key [left right] [K] P
- [key value] query_key [left right] [K] roll<
- [key value] [left right] [K] query_key [roll< uncons swap] dip
+ [key value] query_key [left right] [K] P
+ [key value] query_key [left right] [K] roll<
+ [key value] [left right] [K] query_key [roll< uncons swap] dip
- [key value] [left right] [K] roll< uncons swap query_key
- [left right] [K] [key value] uncons swap query_key
- [left right] [K] key [value] swap query_key
- [left right] [K] [value] key query_key
+ [key value] [left right] [K] roll< uncons swap query_key
+ [left right] [K] [key value] uncons swap query_key
+ [left right] [K] key [value] swap query_key
+ [left right] [K] [value] key query_key
- P == roll< [roll< uncons swap] dip
+ P == roll< [roll< uncons swap] dip
(Possibly with a swap at the end? Or just swap ``T<`` and ``T>``.)
::
- [left right] [K] [value] key query_key [T>] [E] [T<] cmp
+ [left right] [K] [value] key query_key [T>] [E] [T<] cmp
Becomes one of these three:
::
- [left right] [K] [value] T>
- [left right] [K] [value] E
- [left right] [K] [value] T<
+ [left right] [K] [value] T>
+ [left right] [K] [value] E
+ [left right] [K] [value] T<
``E``
~~~~~
::
- E == roll> popop first
+ E == roll> popop first
``T<`` and ``T>``
~~~~~~~~~~~~~~~~~
::
- T< == pop [first] dip i
- T> == pop [second] dip i
+ T< == pop [first] dip i
+ T> == pop [second] dip i
Putting it together
-------------------
::
- T> == pop [first] dip i
- T< == pop [second] dip i
- E == roll> popop first
- P == roll< [roll< uncons swap] dip
+ T> == pop [first] dip i
+ T< == pop [second] dip i
+ E == roll> popop first
+ P == roll< [roll< uncons swap] dip
- Tree-get == [P [T>] [E] [T<] cmp] treegrind
+ Tree-get == [P [T>] [E] [T<] cmp] treegrind
To me, that seems simpler than the ``genrec`` version.
(... [3 4 ] 2 1 0 -- ... [1 2 ])
-Unification Works "in Reverse"
+Unification Works “in Reverse”
------------------------------
.. code:: ipython2
===================================
This notebook presents a simple type inferencer for Joy code. It can
-infer the stack effect of most Joy expressions. It's built largely by
+infer the stack effect of most Joy expressions. It’s built largely by
means of existing ideas and research. (A great overview of the existing
-knowledge is a talk `"Type Inference in Stack-Based Programming
-Languages" <http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/>`__
+knowledge is a talk `“Type Inference in Stack-Based Programming
+Languages” <http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/>`__
given by Rob Kleffner on or about 2017-03-10 as part of a course on the
history of programming languages.)
The notebook starts with a simple inferencer based on the work of Jaanus
Pöial which we then progressively elaborate to cover more Joy semantics.
-Along the way we write a simple "compiler" that emits Python code for
+Along the way we write a simple “compiler” that emits Python code for
what I like to call Yin functions. (Yin functions are those that only
rearrange values in stacks, as opposed to Yang functions that actually
work on the values themselves.)
-Part I: Pöial's Rules
+Part I: Pöial’s Rules
---------------------
-`"Typing Tools for Typeless Stack Languages" by Jaanus
+`“Typing Tools for Typeless Stack Languages” by Jaanus
Pöial <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.212.6026>`__
::
- @INPROCEEDINGS{Pöial06typingtools,
- author = {Jaanus Pöial},
- title = {Typing tools for typeless stack languages},
- booktitle = {In 23rd Euro-Forth Conference},
- year = {2006},
- pages = {40--46}
- }
+ @INPROCEEDINGS{Pöial06typingtools,
+ author = {Jaanus Pöial},
+ title = {Typing tools for typeless stack languages},
+ booktitle = {In 23rd Euro-Forth Conference},
+ year = {2006},
+ pages = {40--46}
+ }
First Rule
~~~~~~~~~~
::
- (a -- b)∘(-- d)
- ---------------------
- (a -- b d)
+ (a -- b)∘(-- d)
+ ---------------------
+ (a -- b d)
Second Rule
~~~~~~~~~~~
::
- (a --)∘(c -- d)
- ---------------------
- (c a -- d)
+ (a --)∘(c -- d)
+ ---------------------
+ (c a -- d)
Third Rule
~~~~~~~~~~
The third rule is actually two rules. These two rules deal with
composing functions when the second one will consume one of items the
first one produces. The two types must be
-`*unified* <https://en.wikipedia.org/wiki/Robinson's_unification_algorithm>`__
+`unified <https://en.wikipedia.org/wiki/Robinson's_unification_algorithm>`__
or a type conflict declared.
::
- (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
- -------------------------------
- (a -- b )∘(c -- d) t[i] == t[k] == u[j]
- ^
+ (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == t[k] == u[j]
+ ^
- (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
- -------------------------------
- (a -- b )∘(c -- d) t[i] == u[k] == u[j]
+ (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == u[k] == u[j]
-Let's work through some examples by hand to develop an intuition for the
+Let’s work through some examples by hand to develop an intuition for the
algorithm.
-There's a function in one of the other notebooks.
+There’s a function in one of the other notebooks.
::
- F == pop swap roll< rest rest cons cons
+ F == pop swap roll< rest rest cons cons
-It's all "stack chatter" and list manipulation so we should be able to
+It’s all “stack chatter” and list manipulation so we should be able to
deduce its type.
Stack Effect Comments
~~~~~~~~~~~~~~~~~~~~~
Joy function types will be represented by Forth-style stack effect
-comments. I'm going to use numbers instead of names to keep track of the
+comments. I’m going to use numbers instead of names to keep track of the
stack arguments. (A little bit like `De Bruijn
index <https://en.wikipedia.org/wiki/De_Bruijn_index>`__, at least it
reminds me of them):
::
- pop (1 --)
+ pop (1 --)
- swap (1 2 -- 2 1)
+ swap (1 2 -- 2 1)
- roll< (1 2 3 -- 2 3 1)
+ roll< (1 2 3 -- 2 3 1)
-These commands alter the stack but don't "look at" the values so these
-numbers represent an "Any type".
+These commands alter the stack but don’t “look at” the values so these
+numbers represent an “Any type”.
``pop swap``
~~~~~~~~~~~~
::
- (1 --) (1 2 -- 2 1)
+ (1 --) (1 2 -- 2 1)
Here we encounter a complication. The argument numbers need to be made
-unique among both sides. For this let's change ``pop`` to use 0:
+unique among both sides. For this let’s change ``pop`` to use 0:
::
- (0 --) (1 2 -- 2 1)
+ (0 --) (1 2 -- 2 1)
Following the second rule:
::
- (1 2 0 -- 2 1)
+ (1 2 0 -- 2 1)
``pop∘swap roll<``
~~~~~~~~~~~~~~~~~~
::
- (1 2 0 -- 2 1) (1 2 3 -- 2 3 1)
+ (1 2 0 -- 2 1) (1 2 3 -- 2 3 1)
-Let's re-label them:
+Let’s re-label them:
::
- (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
+ (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
Now we follow the rules.
::
- (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
- w/ {1a: 3b}
- (3b 2a 0a -- 2a ) (1b 2b -- 2b 3b 1b)
- w/ {2a: 2b}
- (3b 2b 0a -- ) (1b -- 2b 3b 1b)
+ (1a 2a 0a -- 2a 1a) (1b 2b 3b -- 2b 3b 1b)
+ w/ {1a: 3b}
+ (3b 2a 0a -- 2a ) (1b 2b -- 2b 3b 1b)
+ w/ {2a: 2b}
+ (3b 2b 0a -- ) (1b -- 2b 3b 1b)
Here we must apply the second rule:
::
- (3b 2b 0a --) (1b -- 2b 3b 1b)
- -----------------------------------
- (1b 3b 2b 0a -- 2b 3b 1b)
+ (3b 2b 0a --) (1b -- 2b 3b 1b)
+ -----------------------------------
+ (1b 3b 2b 0a -- 2b 3b 1b)
Now we de-label the type, uh, labels:
::
- (1b 3b 2b 0a -- 2b 3b 1b)
+ (1b 3b 2b 0a -- 2b 3b 1b)
- w/ {
- 1b: 1,
- 3b: 2,
- 2b: 3,
- 0a: 0,
- }
+ w/ {
+ 1b: 1,
+ 3b: 2,
+ 2b: 3,
+ 0a: 0,
+ }
- (1 2 3 0 -- 3 2 1)
+ (1 2 3 0 -- 3 2 1)
And now we have the stack effect comment for ``pop∘swap∘roll<``.
Compiling ``pop∘swap∘roll<``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The simplest way to "compile" this function would be something like:
+The simplest way to “compile” this function would be something like:
.. code:: ipython2
::
- (1 2 3 0 -- 3 2 1)
+ (1 2 3 0 -- 3 2 1)
We should be able to directly write out a Python function like:
return (c, (b, (a, stack)))
This eliminates the internal work of the first version. Because this
-function only rearranges the stack and doesn't do any actual processing
+function only rearranges the stack and doesn’t do any actual processing
on the stack items themselves all the information needed to implement it
is in the stack effect comment.
::
- rest ( [1 ...] -- [...] )
+ rest ( [1 ...] -- [...] )
- cons ( 1 [...] -- [1 ...] )
+ cons ( 1 [...] -- [1 ...] )
``pop∘swap∘roll< rest``
~~~~~~~~~~~~~~~~~~~~~~~
::
- (1 2 3 0 -- 3 2 1) ([1 ...] -- [...])
+ (1 2 3 0 -- 3 2 1) ([1 ...] -- [...])
-Re-label (instead of adding left and right tags I'm just taking the next
+Re-label (instead of adding left and right tags I’m just taking the next
available index number for the right-side stack effect comment):
::
- (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
+ (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
Unify and update:
::
- (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
- w/ {1: [4 ...]}
- ([4 ...] 2 3 0 -- 3 2 ) ( -- [...])
+ (1 2 3 0 -- 3 2 1) ([4 ...] -- [...])
+ w/ {1: [4 ...]}
+ ([4 ...] 2 3 0 -- 3 2 ) ( -- [...])
Apply the first rule:
::
- ([4 ...] 2 3 0 -- 3 2) (-- [...])
- ---------------------------------------
- ([4 ...] 2 3 0 -- 3 2 [...])
+ ([4 ...] 2 3 0 -- 3 2) (-- [...])
+ ---------------------------------------
+ ([4 ...] 2 3 0 -- 3 2 [...])
And there we are.
``pop∘swap∘roll<∘rest rest``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Let's do it again.
+Let’s do it again.
::
- ([4 ...] 2 3 0 -- 3 2 [...]) ([1 ...] -- [...])
+ ([4 ...] 2 3 0 -- 3 2 [...]) ([1 ...] -- [...])
Re-label (the tails of the lists on each side each get their own label):
::
- ([4 .0.] 2 3 0 -- 3 2 [.0.]) ([5 .1.] -- [.1.])
+ ([4 .0.] 2 3 0 -- 3 2 [.0.]) ([5 .1.] -- [.1.])
Unify and update (note the opening square brackets have been omited in
-the substitution dict, this is deliberate and I'll explain below):
+the substitution dict, this is deliberate and I’ll explain below):
::
- ([4 .0.] 2 3 0 -- 3 2 [.0.] ) ([5 .1.] -- [.1.])
- w/ { .0.] : 5 .1.] }
- ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
+ ([4 .0.] 2 3 0 -- 3 2 [.0.] ) ([5 .1.] -- [.1.])
+ w/ { .0.] : 5 .1.] }
+ ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
How do we find ``.0.]`` in ``[4 .0.]`` and replace it with ``5 .1.]``
getting the result ``[4 5 .1.]``? This might seem hard, but because the
-underlying structure of the Joy list is a cons-list in Python it's
-actually pretty easy. I'll explain below.
+underlying structure of the Joy list is a cons-list in Python it’s
+actually pretty easy. I’ll explain below.
Next we unify and find our two terms are the same already: ``[5 .1.]``:
::
- ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
+ ([4 5 .1.] 2 3 0 -- 3 2 [5 .1.]) ([5 .1.] -- [.1.])
Giving us:
::
- ([4 5 .1.] 2 3 0 -- 3 2) (-- [.1.])
+ ([4 5 .1.] 2 3 0 -- 3 2) (-- [.1.])
From here we apply the first rule and get:
::
- ([4 5 .1.] 2 3 0 -- 3 2 [.1.])
+ ([4 5 .1.] 2 3 0 -- 3 2 [.1.])
Cleaning up the labels:
::
- ([4 5 ...] 2 3 1 -- 3 2 [...])
+ ([4 5 ...] 2 3 1 -- 3 2 [...])
This is the stack effect of ``pop∘swap∘roll<∘rest∘rest``.
::
- ([4 5 ...] 2 3 1 -- 3 2 [...]) (1 [...] -- [1 ...])
+ ([4 5 ...] 2 3 1 -- 3 2 [...]) (1 [...] -- [1 ...])
Re-label:
::
- ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
+ ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
Unify:
::
- ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
- w/ { .1.] : .2.] }
- ([4 5 .2.] 2 3 1 -- 3 2 ) (6 -- [6 .2.])
- w/ {2: 6}
- ([4 5 .2.] 6 3 1 -- 3 ) ( -- [6 .2.])
+ ([4 5 .1.] 2 3 1 -- 3 2 [.1.]) (6 [.2.] -- [6 .2.])
+ w/ { .1.] : .2.] }
+ ([4 5 .2.] 2 3 1 -- 3 2 ) (6 -- [6 .2.])
+ w/ {2: 6}
+ ([4 5 .2.] 6 3 1 -- 3 ) ( -- [6 .2.])
First rule:
::
- ([4 5 .2.] 6 3 1 -- 3 [6 .2.])
+ ([4 5 .2.] 6 3 1 -- 3 [6 .2.])
Re-label:
::
- ([4 5 ...] 2 3 1 -- 3 [2 ...])
+ ([4 5 ...] 2 3 1 -- 3 [2 ...])
Done.
::
- ([4 5 ...] 2 3 1 -- 3 [2 ...]) (1 [...] -- [1 ...])
+ ([4 5 ...] 2 3 1 -- 3 [2 ...]) (1 [...] -- [1 ...])
Re-label:
::
- ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.])
+ ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.])
Unify:
::
- ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.] )
- w/ { .2.] : 2 .1.] }
- ([4 5 .1.] 2 3 1 -- 3 ) (6 -- [6 2 .1.])
- w/ {3: 6}
- ([4 5 .1.] 2 6 1 -- ) ( -- [6 2 .1.])
+ ([4 5 .1.] 2 3 1 -- 3 [2 .1.]) (6 [.2.] -- [6 .2.] )
+ w/ { .2.] : 2 .1.] }
+ ([4 5 .1.] 2 3 1 -- 3 ) (6 -- [6 2 .1.])
+ w/ {3: 6}
+ ([4 5 .1.] 2 6 1 -- ) ( -- [6 2 .1.])
First or second rule:
::
- ([4 5 .1.] 2 6 1 -- [6 2 .1.])
+ ([4 5 .1.] 2 6 1 -- [6 2 .1.])
Clean up the labels:
::
- ([4 5 ...] 2 3 1 -- [3 2 ...])
+ ([4 5 ...] 2 3 1 -- [3 2 ...])
And there you have it, the stack effect for
``pop∘swap∘roll<∘rest∘rest∘cons∘cons``.
::
- ([4 5 ...] 2 3 1 -- [3 2 ...])
+ ([4 5 ...] 2 3 1 -- [3 2 ...])
From this stack effect comment it should be possible to construct the
following Python code:
Representing Stack Effect Comments in Python
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-I'm going to use pairs of tuples of type descriptors, which will be
+I’m going to use pairs of tuples of type descriptors, which will be
integers or tuples of type descriptors:
.. code:: ipython2
At last we put it all together in a function ``C()`` that accepts two
stack effect comments and returns their composition (or raises and
-exception if they can't be composed due to type conflicts.)
+exception if they can’t be composed due to type conflicts.)
.. code:: ipython2
fg = compose(f, g)
return delabel(fg)
-Let's try it out.
+Let’s try it out.
.. code:: ipython2
Stack Functions
~~~~~~~~~~~~~~~
-Here's that trick to represent functions like ``rest`` and ``cons`` that
+Here’s that trick to represent functions like ``rest`` and ``cons`` that
manipulate stacks. We use a cons-list of tuples and give the tails their
own numbers. Then everything above already works.
::
- (( (3, 4), 1, 2, 0 ), ( 2, 1, 4 ))
- ( [4 ...] 2 3 0 -- 3 2 [...])
+ (( (3, 4), 1, 2, 0 ), ( 2, 1, 4 ))
+ ( [4 ...] 2 3 0 -- 3 2 [...])
The translation table, if you will, would be:
::
- {
- 3: 4,
- 4: ...],
- 1: 2,
- 2: 3,
- 0: 0,
- }
+ {
+ 3: 4,
+ 4: ...],
+ 1: 2,
+ 2: 3,
+ 0: 0,
+ }
.. code:: ipython2
::
- ([4 5 ...] 2 3 1 -- [3 2 ...])
- 3 4 5 1 2 0 2 1 5
+ ([4 5 ...] 2 3 1 -- [3 2 ...])
+ 3 4 5 1 2 0 2 1 5
Dealing with ``cons`` and ``uncons``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-However, if we try to compose e.g. ``cons`` and ``uncons`` it won't
+However, if we try to compose e.g. ``cons`` and ``uncons`` it won’t
work:
.. code:: ipython2
``unify()`` version 2
^^^^^^^^^^^^^^^^^^^^^
-The problem is that the ``unify()`` function as written doesn't handle
+The problem is that the ``unify()`` function as written doesn’t handle
the case when both terms are tuples. We just have to add a clause to
deal with this recursively:
::
- (_, (d, (c, ((a, (b, S0)), stack))))
+ (_, (d, (c, ((a, (b, S0)), stack))))
Remove the punctuation:
::
- _ d c (a, (b, S0))
+ _ d c (a, (b, S0))
Reverse the order and compare:
::
- (a, (b, S0)) c d _
- ((3, (4, 5 )), 1, 2, 0)
+ (a, (b, S0)) c d _
+ ((3, (4, 5 )), 1, 2, 0)
Eh?
::
- ((d, (c, S0)), stack)
- ((2, (1, 5 )), )
+ ((d, (c, S0)), stack)
+ ((2, (1, 5 )), )
This should make it pretty easy to write a Python function that accepts
the stack effect comment tuples and returns a new Python function
Python Identifiers
~~~~~~~~~~~~~~~~~~
-We want to substitute Python identifiers for the integers. I'm going to
+We want to substitute Python identifiers for the integers. I’m going to
repurpose ``joy.parser.Symbol`` class for this:
.. code:: ipython2
``doc_from_stack_effect()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-As a convenience I've implemented a function to convert the Python stack
+As a convenience I’ve implemented a function to convert the Python stack
effect comment tuples to reasonable text format. There are some details
in how this code works that related to stuff later in the notebook, so
-you should skip it for now and read it later if you're interested.
+you should skip it for now and read it later if you’re interested.
.. code:: ipython2
-Let's try it out:
+Let’s try it out:
.. code:: ipython2
With this, we have a partial Joy compiler that works on the subset of
-Joy functions that manipulate stacks (both what I call "stack chatter"
+Joy functions that manipulate stacks (both what I call “stack chatter”
and the ones that manipulate stacks on the stack.)
-I'm probably going to modify the definition wrapper code to detect
+I’m probably going to modify the definition wrapper code to detect
definitions that can be compiled by this partial compiler and do it
automatically. It might be a reasonable idea to detect sequences of
compilable functions in definitions that have uncompilable functions in
----------------------------------------
So far we have dealt with types of functions, those dealing with simple
-stack manipulation. Let's extend our machinery to deal with types of
+stack manipulation. Let’s extend our machinery to deal with types of
arguments.
-"Number" Type
+“Number” Type
~~~~~~~~~~~~~
Consider the definition of ``sqr``:
::
- sqr == dup mul
+ sqr == dup mul
The ``dup`` function accepts one *anything* and returns two of that:
::
- dup (1 -- 1 1)
+ dup (1 -- 1 1)
-And ``mul`` accepts two "numbers" (we're ignoring ints vs. floats vs.
-complex, etc., for now) and returns just one:
+And ``mul`` accepts two “numbers” (we’re ignoring ints vs. floats
+vs. complex, etc., for now) and returns just one:
::
- mul (n n -- n)
+ mul (n n -- n)
-So we're composing:
+So we’re composing:
::
- (1 -- 1 1)∘(n n -- n)
+ (1 -- 1 1)∘(n n -- n)
The rules say we unify 1 with ``n``:
::
- (1 -- 1 1)∘(n n -- n)
- --------------------------- w/ {1: n}
- (1 -- 1 )∘(n -- n)
+ (1 -- 1 1)∘(n n -- n)
+ --------------------------- w/ {1: n}
+ (1 -- 1 )∘(n -- n)
-This involves detecting that "Any type" arguments can accept "numbers".
+This involves detecting that “Any type” arguments can accept “numbers”.
If we were composing these functions the other way round this is still
the case:
::
- (n n -- n)∘(1 -- 1 1)
- --------------------------- w/ {1: n}
- (n n -- )∘( -- n n)
+ (n n -- n)∘(1 -- 1 1)
+ --------------------------- w/ {1: n}
+ (n n -- )∘( -- n n)
The important thing here is that the mapping is going the same way in
-both cases, from the "any" integer to the number
+both cases, from the “any” integer to the number
Distinguishing Numbers
~~~~~~~~~~~~~~~~~~~~~~
::
- mul (n2 n1 -- n3)
+ mul (n2 n1 -- n3)
- (1 -- 1 1)∘(n2 n1 -- n3)
- -------------------------------- w/ {1: n2}
- (n2 -- n2 )∘(n2 -- n3)
+ (1 -- 1 1)∘(n2 n1 -- n3)
+ -------------------------------- w/ {1: n2}
+ (n2 -- n2 )∘(n2 -- n3)
- (n2 n1 -- n3)∘(1 -- 1 1 )
- -------------------------------- w/ {1: n3}
- (n2 n1 -- )∘( -- n3 n3)
+ (n2 n1 -- n3)∘(1 -- 1 1 )
+ -------------------------------- w/ {1: n3}
+ (n2 n1 -- )∘( -- n3 n3)
Distinguishing Types
~~~~~~~~~~~~~~~~~~~~
-So we need separate domains of "any" numbers and "number" numbers, and
+So we need separate domains of “any” numbers and “number” numbers, and
we need to be able to ask the order of these domains. Now the notes on
the right side of rule three make more sense, eh?
::
- (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
- -------------------------------
- (a -- b )∘(c -- d) t[i] == t[k] == u[j]
- ^
+ (a -- b t[i])∘(c u[j] -- d) t <= u (t is subtype of u)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == t[k] == u[j]
+ ^
- (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
- -------------------------------
- (a -- b )∘(c -- d) t[i] == u[k] == u[j]
+ (a -- b t[i])∘(c u[j] -- d) u <= t (u is subtype of t)
+ -------------------------------
+ (a -- b )∘(c -- d) t[i] == u[k] == u[j]
The indices ``i``, ``k``, and ``j`` are the number part of our labels
and ``t`` and ``u`` are the domains.
-By creative use of Python's "double underscore" methods we can define a
+By creative use of Python’s “double underscore” methods we can define a
Python class hierarchy of Joy types and use the ``issubclass()`` method
to establish domain ordering, as well as other handy behaviour that will
make it fairly easy to reuse most of the code above.
from itertools import permutations
-"Any" types can be specialized to numbers and stacks, but not vice
+“Any” types can be specialized to numbers and stacks, but not vice
versa:
.. code:: ipython2
Our crude `Numerical
Tower <https://en.wikipedia.org/wiki/Numerical_tower>`__ of *numbers* >
-*floats* > *integers* works as well (but we're not going to use it yet):
+*floats* > *integers* works as well (but we’re not going to use it yet):
.. code:: ipython2
^^^^^^^^^^^^^^^^^^^^^^^
The ``delabel()`` function needs an overhaul. It now has to keep track
-of how many labels of each domain it has "seen".
+of how many labels of each domain it has “seen”.
.. code:: ipython2
^^^^^^^^^^^^^^^^^^^^^^^^
Because the type labels represent themselves as valid Python identifiers
-the ``compile_()`` function doesn't need to generate them anymore:
+the ``compile_()`` function doesn’t need to generate them anymore:
.. code:: ipython2
return ((a4, (a3, s1)), stack)
-But it cannot magically create new functions that involve e.g. math and
+But it cannot magically create new functions that involve e.g. math and
such. Note that this is *not* a ``sqr`` function implementation:
.. code:: ipython2
return (n2, stack)
-(Eventually I should come back around to this becuase it's not tooo
+(Eventually I should come back around to this becuase it’s not tooo
difficult to exend this code to be able to compile e.g.
``n2 = mul(n1, n1)`` for ``mul`` with the right variable names and
insert it in the right place. It requires a little more support from the
::
- stack (... -- ... [...] )
- stack (... a -- ... a [a ...] )
- stack (... b a -- ... b a [a b ...])
+ stack (... -- ... [...] )
+ stack (... a -- ... a [a ...] )
+ stack (... b a -- ... b a [a b ...])
We would like to represent this in Python somehow. To do this we use a
simple, elegant trick.
::
- stack S -- ( S, S)
- stack (a, S) -- ( (a, S), (a, S))
- stack (a, (b, S)) -- ( (a, (b, S)), (a, (b, S)))
+ stack S -- ( S, S)
+ stack (a, S) -- ( (a, S), (a, S))
+ stack (a, (b, S)) -- ( (a, (b, S)), (a, (b, S)))
Instead of representing the stack effect comments as a single tuple
(with N items in it) we use the same cons-list structure to hold the
``stack∘uncons``
~~~~~~~~~~~~~~~~
-Let's try composing ``stack`` and ``uncons``. We want this result:
+Let’s try composing ``stack`` and ``uncons``. We want this result:
::
- stack∘uncons (... a -- ... a a [...])
+ stack∘uncons (... a -- ... a a [...])
The stack effects are:
::
- stack = S -- (S, S)
+ stack = S -- (S, S)
- uncons = ((a, Z), S) -- (Z, (a, S))
+ uncons = ((a, Z), S) -- (Z, (a, S))
Unifying:
::
- S -- (S, S) ∘ ((a, Z), S) -- (Z, (a, S ))
- w/ { S: (a, Z) }
- (a, Z) -- ∘ -- (Z, (a, (a, Z)))
+ S -- (S, S) ∘ ((a, Z), S) -- (Z, (a, S ))
+ w/ { S: (a, Z) }
+ (a, Z) -- ∘ -- (Z, (a, (a, Z)))
So:
::
- stack∘uncons == (a, Z) -- (Z, (a, (a, Z)))
+ stack∘uncons == (a, Z) -- (Z, (a, (a, Z)))
It works.
``stack∘uncons∘uncons``
~~~~~~~~~~~~~~~~~~~~~~~
-Let's try ``stack∘uncons∘uncons``:
+Let’s try ``stack∘uncons∘uncons``:
::
- (a, S ) -- (S, (a, (a, S ))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
+ (a, S ) -- (S, (a, (a, S ))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
- w/ { S: (b, Z) }
-
- (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
+ w/ { S: (b, Z) }
+
+ (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), S` ) -- (Z, (b, S` ))
- w/ { S`: (a, (a, (b, Z))) }
-
- (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), (a, (a, (b, Z)))) -- (Z, (b, (a, (a, (b, Z)))))
+ w/ { S`: (a, (a, (b, Z))) }
+
+ (a, (b, Z)) -- ((b, Z), (a, (a, (b, Z)))) ∘ ((b, Z), (a, (a, (b, Z)))) -- (Z, (b, (a, (a, (b, Z)))))
- (a, (b, Z)) -- (Z, (b, (a, (a, (b, Z)))))
+ (a, (b, Z)) -- (Z, (b, (a, (a, (b, Z)))))
It works.
This function has to be modified to use the new datastructures and it is
no longer recursive, instead recursion happens as part of unification.
-Further, the first and second of Pöial's rules are now handled
+Further, the first and second of Pöial’s rules are now handled
automatically by the unification algorithm. (One easy way to see this is
that now an empty stack effect comment is represented by a
-``StackJoyType`` instance which is not "falsey" and so neither of the
-first two rules' ``if`` clauses will ever be ``True``. Later on I change
-the "truthiness" of ``StackJoyType`` to false to let e.g.
+``StackJoyType`` instance which is not “falsey” and so neither of the
+first two rules’ ``if`` clauses will ever be ``True``. Later on I change
+the “truthiness” of ``StackJoyType`` to false to let e.g.
``joy.utils.stack.concat`` work with our stack effect comment cons-list
tuples.)
raise TypeError('Cannot unify %r and %r.' % (f_out, g_in))
return update(s, (f_in, g_out))
-I don't want to rewrite all the defs myself, so I'll write a little
-conversion function instead. This is programmer's laziness.
+I don’t want to rewrite all the defs myself, so I’ll write a little
+conversion function instead. This is programmer’s laziness.
.. code:: ipython2
Part VI: Multiple Stack Effects
-------------------------------
-...
+…
.. code:: ipython2
Representing an Unbounded Sequence of Types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-We can borrow a trick from `Brzozowski's Derivatives of Regular
+We can borrow a trick from `Brzozowski’s Derivatives of Regular
Expressions <https://en.wikipedia.org/wiki/Brzozowski_derivative>`__ to
-invent a new type of type variable, a "sequence type" (I think this is
-what they mean in the literature by that term...) or "`Kleene
-Star <https://en.wikipedia.org/wiki/Kleene_star>`__" type. I'm going to
+invent a new type of type variable, a “sequence type” (I think this is
+what they mean in the literature by that term…) or “`Kleene
+Star <https://en.wikipedia.org/wiki/Kleene_star>`__” type. I’m going to
represent it as a type letter and the asterix, so a sequence of zero or
more ``AnyJoyType`` variables would be:
::
- A*
+ A*
The ``A*`` works by splitting the universe into two alternate histories:
::
- A* -> 0 | A A*
+ A* -> 0 | A A*
The Kleene star variable disappears in one universe, and in the other it
turns into an ``AnyJoyType`` variable followed by itself again. We have
to return all universes (represented by their substitution dicts, the
-"unifiers") that don't lead to type conflicts.
+“unifiers”) that don’t lead to type conflicts.
Consider unifying two stacks (the lowercase letters are any type
variables of the kinds we have defined so far):
::
- [a A* b .0.] U [c d .1.]
- w/ {c: a}
- [ A* b .0.] U [ d .1.]
+ [a A* b .0.] U [c d .1.]
+ w/ {c: a}
+ [ A* b .0.] U [ d .1.]
Now we have to split universes to unify ``A*``. In the first universe it
disappears:
::
- [b .0.] U [d .1.]
- w/ {d: b, .1.: .0.}
- [] U []
+ [b .0.] U [d .1.]
+ w/ {d: b, .1.: .0.}
+ [] U []
While in the second it spawns an ``A``, which we will label ``e``:
::
- [e A* b .0.] U [d .1.]
- w/ {d: e}
- [ A* b .0.] U [ .1.]
- w/ {.1.: A* b .0.}
- [ A* b .0.] U [ A* b .0.]
+ [e A* b .0.] U [d .1.]
+ w/ {d: e}
+ [ A* b .0.] U [ .1.]
+ w/ {.1.: A* b .0.}
+ [ A* b .0.] U [ A* b .0.]
Giving us two unifiers:
::
- {c: a, d: b, .1.: .0.}
- {c: a, d: e, .1.: A* b .0.}
+ {c: a, d: b, .1.: .0.}
+ {c: a, d: e, .1.: A* b .0.}
.. code:: ipython2
``unify()`` version 4
^^^^^^^^^^^^^^^^^^^^^
-Can now return multiple results...
+Can now return multiple results…
.. code:: ipython2
::
- (a1*, s1) [a1*] (a1, s2) [a1]
+ (a1*, s1) [a1*] (a1, s2) [a1]
- (a1*, (a1, s2)) [a1* a1] (a1, s2) [a1]
+ (a1*, (a1, s2)) [a1* a1] (a1, s2) [a1]
- (a1*, s1) [a1*] (a2, (a1*, s1)) [a2 a1*]
+ (a1*, s1) [a1*] (a2, (a1*, s1)) [a2 a1*]
.. code:: ipython2
In order to compute the stack effect of combinators you kinda have to
have the quoted programs they expect available. In the most general
-case, the ``i`` combinator, you can't say anything about its stack
+case, the ``i`` combinator, you can’t say anything about its stack
effect other than it expects one quote:
::
- i (... [.1.] -- ... .1.)
+ i (... [.1.] -- ... .1.)
Or
::
- i (... [A* .1.] -- ... A*)
+ i (... [A* .1.] -- ... A*)
Consider the type of:
::
- [cons] dip
+ [cons] dip
Obviously it would be:
::
- (a1 [..1] a2 -- [a1 ..1] a2)
+ (a1 [..1] a2 -- [a1 ..1] a2)
``dip`` itself could have:
::
- (a1 [..1] -- ... then what?
+ (a1 [..1] -- ... then what?
-Without any information about the contents of the quote we can't say
+Without any information about the contents of the quote we can’t say
much about the result.
Hybrid Inferencer/Interpreter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-I think there's a way forward. If we convert our list (of terms we are
+I think there’s a way forward. If we convert our list (of terms we are
composing) into a stack structure we can use it as a *Joy expression*,
-then we can treat the *output half* of a function's stack effect comment
+then we can treat the *output half* of a function’s stack effect comment
as a Joy interpreter stack, and just execute combinators directly. We
can hybridize the compostition function with an interpreter to evaluate
combinators, compose non-combinator functions, and put type variables on
the stack. For combinators like ``branch`` that can have more than one
-stack effect we have to "split universes" again and return both.
+stack effect we have to “split universes” again and return both.
Joy Types for Functions
^^^^^^^^^^^^^^^^^^^^^^^
You can also provide an optional stack effect, input-side only, that
will then be used as an identity function (that accepts and returns
-stacks that match the "guard" stack effect) which will be used to guard
+stacks that match the “guard” stack effect) which will be used to guard
against type mismatches going into the evaluation of the combinator.
``infer()``
And that brings us to current Work-In-Progress. The mixed-mode
inferencer/interpreter ``infer()`` function seems to work well. There
are details I should document, and the rest of the code in the ``types``
-module (FIXME link to its docs here!) should be explained... There is
+module (FIXME link to its docs here!) should be explained… There is
cruft to convert the definitions in ``DEFS`` to the new
``SymbolJoyType`` objects, and some combinators. Here is an example of
output from the current code :
The numbers at the start of the lines are the current depth of the
-Python call stack. They're followed by the current computed stack effect
+Python call stack. They’re followed by the current computed stack effect
(initialized to ``ID``) then the pending expression (the inference of
the stack effect of which is the whole object of the current example.)
::
- 7 (--) ∘ [pred] [mul] [div] [nullary bool] dipd branch
- 8 (-- [pred ...2]) ∘ [mul] [div] [nullary bool] dipd branch
- 9 (-- [pred ...2] [mul ...3]) ∘ [div] [nullary bool] dipd branch
- 10 (-- [pred ...2] [mul ...3] [div ...4]) ∘ [nullary bool] dipd branch
- 11 (-- [pred ...2] [mul ...3] [div ...4] [nullary bool ...5]) ∘ dipd branch
- 15 (-- [pred ...5]) ∘ nullary bool [mul] [div] branch
- 19 (-- [pred ...2]) ∘ [stack] dinfrirst bool [mul] [div] branch
- 20 (-- [pred ...2] [stack ]) ∘ dinfrirst bool [mul] [div] branch
- 22 (-- [pred ...2] [stack ]) ∘ dip infra first bool [mul] [div] branch
- 26 (--) ∘ stack [pred] infra first bool [mul] [div] branch
- 29 (... -- ... [...]) ∘ [pred] infra first bool [mul] [div] branch
- 30 (... -- ... [...] [pred ...1]) ∘ infra first bool [mul] [div] branch
- 34 (--) ∘ pred s1 swaack first bool [mul] [div] branch
- 37 (n1 -- n2) ∘ [n1] swaack first bool [mul] [div] branch
- 38 (... n1 -- ... n2 [n1 ...]) ∘ swaack first bool [mul] [div] branch
- 41 (... n1 -- ... n1 [n2 ...]) ∘ first bool [mul] [div] branch
- 44 (n1 -- n1 n2) ∘ bool [mul] [div] branch
- 47 (n1 -- n1 b1) ∘ [mul] [div] branch
- 48 (n1 -- n1 b1 [mul ...1]) ∘ [div] branch
- 49 (n1 -- n1 b1 [mul ...1] [div ...2]) ∘ branch
- 53 (n1 -- n1) ∘ div
- 56 (f2 f1 -- f3) ∘
- 56 (i1 f1 -- f2) ∘
- 56 (f1 i1 -- f2) ∘
- 56 (i2 i1 -- f1) ∘
- 53 (n1 -- n1) ∘ mul
- 56 (f2 f1 -- f3) ∘
- 56 (i1 f1 -- f2) ∘
- 56 (f1 i1 -- f2) ∘
- 56 (i2 i1 -- i3) ∘
- ----------------------------------------
- (f2 f1 -- f3)
- (i1 f1 -- f2)
- (f1 i1 -- f2)
- (i2 i1 -- f1)
- (i2 i1 -- i3)
+ 7 (--) ∘ [pred] [mul] [div] [nullary bool] dipd branch
+ 8 (-- [pred ...2]) ∘ [mul] [div] [nullary bool] dipd branch
+ 9 (-- [pred ...2] [mul ...3]) ∘ [div] [nullary bool] dipd branch
+ 10 (-- [pred ...2] [mul ...3] [div ...4]) ∘ [nullary bool] dipd branch
+ 11 (-- [pred ...2] [mul ...3] [div ...4] [nullary bool ...5]) ∘ dipd branch
+ 15 (-- [pred ...5]) ∘ nullary bool [mul] [div] branch
+ 19 (-- [pred ...2]) ∘ [stack] dinfrirst bool [mul] [div] branch
+ 20 (-- [pred ...2] [stack ]) ∘ dinfrirst bool [mul] [div] branch
+ 22 (-- [pred ...2] [stack ]) ∘ dip infra first bool [mul] [div] branch
+ 26 (--) ∘ stack [pred] infra first bool [mul] [div] branch
+ 29 (... -- ... [...]) ∘ [pred] infra first bool [mul] [div] branch
+ 30 (... -- ... [...] [pred ...1]) ∘ infra first bool [mul] [div] branch
+ 34 (--) ∘ pred s1 swaack first bool [mul] [div] branch
+ 37 (n1 -- n2) ∘ [n1] swaack first bool [mul] [div] branch
+ 38 (... n1 -- ... n2 [n1 ...]) ∘ swaack first bool [mul] [div] branch
+ 41 (... n1 -- ... n1 [n2 ...]) ∘ first bool [mul] [div] branch
+ 44 (n1 -- n1 n2) ∘ bool [mul] [div] branch
+ 47 (n1 -- n1 b1) ∘ [mul] [div] branch
+ 48 (n1 -- n1 b1 [mul ...1]) ∘ [div] branch
+ 49 (n1 -- n1 b1 [mul ...1] [div ...2]) ∘ branch
+ 53 (n1 -- n1) ∘ div
+ 56 (f2 f1 -- f3) ∘
+ 56 (i1 f1 -- f2) ∘
+ 56 (f1 i1 -- f2) ∘
+ 56 (i2 i1 -- f1) ∘
+ 53 (n1 -- n1) ∘ mul
+ 56 (f2 f1 -- f3) ∘
+ 56 (i1 f1 -- f2) ∘
+ 56 (f1 i1 -- f2) ∘
+ 56 (i2 i1 -- i3) ∘
+ ----------------------------------------
+ (f2 f1 -- f3)
+ (i1 f1 -- f2)
+ (f1 i1 -- f2)
+ (i2 i1 -- f1)
+ (i2 i1 -- i3)
Conclusion
----------
-We built a simple type inferencer, and a kind of crude "compiler" for a
+We built a simple type inferencer, and a kind of crude “compiler” for a
subset of Joy functions. Then we built a more powerful inferencer that
actually does some evaluation and explores branching code paths
- the rest of the library has to be covered
- figure out how to deal with ``loop`` and ``genrec``, etc..
- extend the types to check values (see the appendix)
-- other kinds of "higher order" type variables, OR, AND, etc..
+- other kinds of “higher order” type variables, OR, AND, etc..
- maybe rewrite in Prolog for great good?
- definitions
-- don't permit composition of functions that don't compose
-- auto-compile compilable functions
+
+ - don’t permit composition of functions that don’t compose
+ - auto-compile compilable functions
+
- Compiling more than just the Yin functions.
- getting better visibility (than Python debugger.)
- DOOOOCS!!!! Lots of docs!
-- docstrings all around
-- improve this notebook (it kinda falls apart at the end narratively. I
- went off and just started writing code to see if it would work. It
- does, but now I have to come back and describe here what I did.
+
+ - docstrings all around
+ - improve this notebook (it kinda falls apart at the end
+ narratively. I went off and just started writing code to see if it
+ would work. It does, but now I have to come back and describe here
+ what I did.
Appendix: Joy in the Logical Paradigm
-------------------------------------
For *type checking* to work the type label classes have to be modified
to let ``T >= t`` succeed, where e.g. ``T`` is ``IntJoyType`` and ``t``
is ``int``. If you do that you can take advantage of the *logical
-relational* nature of the stack effect comments to "compute in reverse"
-as it were. There's a working demo of this at the end of the ``types``
-module. But if you're interested in all that you should just use Prolog!
+relational* nature of the stack effect comments to “compute in reverse”
+as it were. There’s a working demo of this at the end of the ``types``
+module. But if you’re interested in all that you should just use Prolog!
Anyhow, type *checking* is a few easy steps away.
Traversing Datastructures with Zippers
======================================
-This notebook is about using the "zipper" with joy datastructures. See
+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
+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.
+it, and rebuild it using the “zipper” technique.
.. code:: ipython2
Trees
-----
-In Joypy there aren't any complex datastructures, just ints, floats,
+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
+(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.
::
- z-down == [] swap uncons swap
- z-up == swons swap shunt
- z-right == [swons] cons dip uncons swap
- z-left == swons [uncons swap] dip swap
+ 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
+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.
``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.
+In Joy we have the ``dip`` and ``infra`` combinators which can “target”
+or “address” any particular item in a Joy tree structure.
.. code:: ipython2
[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
+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
::
- [...] [Q] [dip dip infra dip infra dip infra] Z
- -------------------------------------------------------------
- [...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
-
+ [...] [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.
+The ``Z`` function isn’t hard to make.
.. code:: ipython2
::
- [...] [Q] 'ddididi' Zstr
- -------------------------------------------------------------
- [...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
+ [...] [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.
+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"
+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!
+ [ n [ n [ n n x ...
+ i d i d i d d Bingo!
-------------------------------------------------------------------------------------------
The SymPy package provides a powerful and elegant
-`"thunk" <https://en.wikipedia.org/wiki/Thunk>`__ object that can take
-the place of a numeric value in calculations and "record" the operations
+`“thunk” <https://en.wikipedia.org/wiki/Thunk>`__ object that can take
+the place of a numeric value in calculations and “record” the operations
performed on it.
We can create some of these objects and put them on the Joy stack:
::
- over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
+ over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
The `SypPy
Symbols <http://docs.sympy.org/latest/modules/core.html#module-sympy.core.symbol>`__
will become the symbolic expression of the math operations.
-Unfortunately, the library ``sqrt`` function doesn't work with the SymPy
+Unfortunately, the library ``sqrt`` function doesn’t work with the SymPy
objects:
.. code:: ipython2
-The Python ``math.sqrt()`` function causes the "can't convert expression
-to float" exception but ``sympy.sqrt()`` does not:
+The Python ``math.sqrt()`` function causes the “can’t convert expression
+to float” exception but ``sympy.sqrt()`` does not:
.. code:: ipython2
At some point I will probably make an optional library of Joy wrappers
for SymPy functions, and either load it automatically if SymPy
-installation is available or have a CLI switch or something. There's a
-huge amount of incredibly useful stuff and I don't see why Joy shouldn't
+installation is available or have a CLI switch or something. There’s a
+huge amount of incredibly useful stuff and I don’t see why Joy shouldn’t
expose another interface for using it. (As an example, the symbolic
-expressions can be "lambdafied" into very fast versions, i.e. a function
+expressions can be “lambdafied” into very fast versions, i.e. a function
that takes ``a``, ``b``, and ``c`` and computes the value of the root
using just low-level fast code, bypassing Joy and Python. Also, Numpy,
&c.)
::
- u k 1 # z = 1
- [pop] [Fw] while # the while statement
- popopd # discard u k, "return" z
+ u k 1 # z = 1
+ [pop] [Fw] while # the while statement
+ popopd # discard u k, "return" z
-What's Fw?
+What’s Fw?
::
- u k z [pop odd] [Ft] [] ifte # the if statement
- [2 //] dip # k = k / 2 floordiv
- [sqr] dipd # u = u * u
+ u k z [pop odd] [Ft] [] ifte # the if statement
+ [2 //] dip # k = k / 2 floordiv
+ [sqr] dipd # u = u * u
- [[sqr] dip 2 //] dip # We can merge last two lines.
+ [[sqr] dip 2 //] dip # We can merge last two lines.
Helper function Ft (to compute z = z \* u).
::
- u k z Ft
- ---------------
- u k u*z
+ u k z Ft
+ ---------------
+ u k u*z
- Ft == [over] dip *
+ Ft == [over] dip *
Putting it together:
::
- Ft == [over] dip *
- Fb == [[sqr] dip 2 //] dip
- Fw == [pop odd] [Ft] [] ifte Fb
- F == 1 [pop] [Fw] while popopd
+ Ft == [over] dip *
+ Fb == [[sqr] dip 2 //] dip
+ Fw == [pop odd] [Ft] [] ifte Fb
+ F == 1 [pop] [Fw] while popopd
.. code:: ipython2
32
-In order to elide the tests let's define special versions of ``while``
+In order to elide the tests let’s define special versions of ``while``
and ``ifte``:
.. code:: ipython2
-Let's try partial evaluation by hand and use a "stronger" thunk.
+Let’s try partial evaluation by hand and use a “stronger” thunk.
Caret underscoring indicates terms that form thunks. When an arg is
unavailable for a computation we just postpone it until the arg becomes
::
- u 5 . F
- u 5 . 1 [pop] [Fw] while popopd
- u 5 1 . [pop] [Fw] while popopd
- u 5 1 [pop] . [Fw] while popopd
- u 5 1 [pop] [Fw] . while popopd
- u 5 1 . Fw [pop] [Fw] while popopd
- u 5 1 . [pop odd] [Ft] [] ifte Fb [pop] [Fw] while popopd
- u 5 1 [pop odd] . [Ft] [] ifte Fb [pop] [Fw] while popopd
- u 5 1 [pop odd] [Ft] . [] ifte Fb [pop] [Fw] while popopd
- u 5 1 [pop odd] [Ft] [] . ifte Fb [pop] [Fw] while popopd
- u 5 1 . Ft Fb [pop] [Fw] while popopd
- u 5 1 . [over] dip * Fb [pop] [Fw] while popopd
- u 5 1 [over] . dip * Fb [pop] [Fw] while popopd
- u 5 . over 1 * Fb [pop] [Fw] while popopd
- u 5 u . 1 * Fb [pop] [Fw] while popopd
- u 5 u 1 . * Fb [pop] [Fw] while popopd
- u 5 u . Fb [pop] [Fw] while popopd
- u 5 u . [[sqr] dip 2 //] dip [pop] [Fw] while popopd
- u 5 u [[sqr] dip 2 //] . dip [pop] [Fw] while popopd
- u 5 . [sqr] dip 2 // u [pop] [Fw] while popopd
- u 5 [sqr] . dip 2 // u [pop] [Fw] while popopd
- u . sqr 5 2 // u [pop] [Fw] while popopd
- u . dup mul 5 2 // u [pop] [Fw] while popopd
- u dup * . 5 2 // u [pop] [Fw] while popopd
- ^^^^^^^
+ u 5 . F
+ u 5 . 1 [pop] [Fw] while popopd
+ u 5 1 . [pop] [Fw] while popopd
+ u 5 1 [pop] . [Fw] while popopd
+ u 5 1 [pop] [Fw] . while popopd
+ u 5 1 . Fw [pop] [Fw] while popopd
+ u 5 1 . [pop odd] [Ft] [] ifte Fb [pop] [Fw] while popopd
+ u 5 1 [pop odd] . [Ft] [] ifte Fb [pop] [Fw] while popopd
+ u 5 1 [pop odd] [Ft] . [] ifte Fb [pop] [Fw] while popopd
+ u 5 1 [pop odd] [Ft] [] . ifte Fb [pop] [Fw] while popopd
+ u 5 1 . Ft Fb [pop] [Fw] while popopd
+ u 5 1 . [over] dip * Fb [pop] [Fw] while popopd
+ u 5 1 [over] . dip * Fb [pop] [Fw] while popopd
+ u 5 . over 1 * Fb [pop] [Fw] while popopd
+ u 5 u . 1 * Fb [pop] [Fw] while popopd
+ u 5 u 1 . * Fb [pop] [Fw] while popopd
+ u 5 u . Fb [pop] [Fw] while popopd
+ u 5 u . [[sqr] dip 2 //] dip [pop] [Fw] while popopd
+ u 5 u [[sqr] dip 2 //] . dip [pop] [Fw] while popopd
+ u 5 . [sqr] dip 2 // u [pop] [Fw] while popopd
+ u 5 [sqr] . dip 2 // u [pop] [Fw] while popopd
+ u . sqr 5 2 // u [pop] [Fw] while popopd
+ u . dup mul 5 2 // u [pop] [Fw] while popopd
+ u dup * . 5 2 // u [pop] [Fw] while popopd
+ ^^^^^^^
::
- u dup * 2 u [pop] [Fw] . while popopd
- u dup * 2 u . Fw [pop] [Fw] while popopd
- u dup * 2 u . [pop odd] [Ft] [] ifte Fb [pop] [Fw] while popopd
- u dup * 2 u [pop odd] . [Ft] [] ifte Fb [pop] [Fw] while popopd
- u dup * 2 u [pop odd] [Ft] . [] ifte Fb [pop] [Fw] while popopd
- u dup * 2 u [pop odd] [Ft] [] . ifte Fb [pop] [Fw] while popopd
- u dup * 2 u . Fb [pop] [Fw] while popopd
- u dup * 2 u . [[sqr] dip 2 //] dip [pop] [Fw] while popopd
- u dup * 2 u [[sqr] dip 2 //] . dip [pop] [Fw] while popopd
- u dup * 2 . [sqr] dip 2 // u [pop] [Fw] while popopd
- u dup * 2 [sqr] . dip 2 // u [pop] [Fw] while popopd
- u dup * . sqr 2 2 // u [pop] [Fw] while popopd
- u dup * . dup mul 2 2 // u [pop] [Fw] while popopd
- u dup * dup * . 2 2 // u [pop] [Fw] while popopd
- ^^^^^^^^^^^^^
+ u dup * 2 u [pop] [Fw] . while popopd
+ u dup * 2 u . Fw [pop] [Fw] while popopd
+ u dup * 2 u . [pop odd] [Ft] [] ifte Fb [pop] [Fw] while popopd
+ u dup * 2 u [pop odd] . [Ft] [] ifte Fb [pop] [Fw] while popopd
+ u dup * 2 u [pop odd] [Ft] . [] ifte Fb [pop] [Fw] while popopd
+ u dup * 2 u [pop odd] [Ft] [] . ifte Fb [pop] [Fw] while popopd
+ u dup * 2 u . Fb [pop] [Fw] while popopd
+ u dup * 2 u . [[sqr] dip 2 //] dip [pop] [Fw] while popopd
+ u dup * 2 u [[sqr] dip 2 //] . dip [pop] [Fw] while popopd
+ u dup * 2 . [sqr] dip 2 // u [pop] [Fw] while popopd
+ u dup * 2 [sqr] . dip 2 // u [pop] [Fw] while popopd
+ u dup * . sqr 2 2 // u [pop] [Fw] while popopd
+ u dup * . dup mul 2 2 // u [pop] [Fw] while popopd
+ u dup * dup * . 2 2 // u [pop] [Fw] while popopd
+ ^^^^^^^^^^^^^
w/ ``K == u dup * dup *``
::
- K 1 u [pop] [Fw] . while popopd
- K 1 u . Fw [pop] [Fw] while popopd
- K 1 u . [pop odd] [Ft] [] ifte Fb [pop] [Fw] while popopd
- K 1 u [pop odd] . [Ft] [] ifte Fb [pop] [Fw] while popopd
- K 1 u [pop odd] [Ft] . [] ifte Fb [pop] [Fw] while popopd
- K 1 u [pop odd] [Ft] [] . ifte Fb [pop] [Fw] while popopd
- K 1 u . Ft Fb [pop] [Fw] while popopd
- K 1 u . [over] dip * Fb [pop] [Fw] while popopd
- K 1 u [over] . dip * Fb [pop] [Fw] while popopd
- K 1 . over u * Fb [pop] [Fw] while popopd
- K 1 K . u * Fb [pop] [Fw] while popopd
- K 1 K u . * Fb [pop] [Fw] while popopd
- K 1 K u * . Fb [pop] [Fw] while popopd
- ^^^^^
+ K 1 u [pop] [Fw] . while popopd
+ K 1 u . Fw [pop] [Fw] while popopd
+ K 1 u . [pop odd] [Ft] [] ifte Fb [pop] [Fw] while popopd
+ K 1 u [pop odd] . [Ft] [] ifte Fb [pop] [Fw] while popopd
+ K 1 u [pop odd] [Ft] . [] ifte Fb [pop] [Fw] while popopd
+ K 1 u [pop odd] [Ft] [] . ifte Fb [pop] [Fw] while popopd
+ K 1 u . Ft Fb [pop] [Fw] while popopd
+ K 1 u . [over] dip * Fb [pop] [Fw] while popopd
+ K 1 u [over] . dip * Fb [pop] [Fw] while popopd
+ K 1 . over u * Fb [pop] [Fw] while popopd
+ K 1 K . u * Fb [pop] [Fw] while popopd
+ K 1 K u . * Fb [pop] [Fw] while popopd
+ K 1 K u * . Fb [pop] [Fw] while popopd
+ ^^^^^
w/ ``L == K u *``
::
- K 1 L . Fb [pop] [Fw] while popopd
- K 1 L . [[sqr] dip 2 //] dip [pop] [Fw] while popopd
- K 1 L [[sqr] dip 2 //] . dip [pop] [Fw] while popopd
- K 1 . [sqr] dip 2 // L [pop] [Fw] while popopd
- K 1 [sqr] . dip 2 // L [pop] [Fw] while popopd
- K . sqr 1 2 // L [pop] [Fw] while popopd
- K . dup mul 1 2 // L [pop] [Fw] while popopd
- K K . mul 1 2 // L [pop] [Fw] while popopd
- K K * . 1 2 // L [pop] [Fw] while popopd
- ^^^^^
- K K * . 1 2 // L [pop] [Fw] while popopd
- K K * 1 . 2 // L [pop] [Fw] while popopd
- K K * 1 2 . // L [pop] [Fw] while popopd
- K K * 0 . L [pop] [Fw] while popopd
- K K * 0 L . [pop] [Fw] while popopd
- K K * 0 L [pop] . [Fw] while popopd
- K K * 0 L [pop] [Fw] . while popopd
- ^^^^^
- K K * 0 L . popopd
- L .
+ K 1 L . Fb [pop] [Fw] while popopd
+ K 1 L . [[sqr] dip 2 //] dip [pop] [Fw] while popopd
+ K 1 L [[sqr] dip 2 //] . dip [pop] [Fw] while popopd
+ K 1 . [sqr] dip 2 // L [pop] [Fw] while popopd
+ K 1 [sqr] . dip 2 // L [pop] [Fw] while popopd
+ K . sqr 1 2 // L [pop] [Fw] while popopd
+ K . dup mul 1 2 // L [pop] [Fw] while popopd
+ K K . mul 1 2 // L [pop] [Fw] while popopd
+ K K * . 1 2 // L [pop] [Fw] while popopd
+ ^^^^^
+ K K * . 1 2 // L [pop] [Fw] while popopd
+ K K * 1 . 2 // L [pop] [Fw] while popopd
+ K K * 1 2 . // L [pop] [Fw] while popopd
+ K K * 0 . L [pop] [Fw] while popopd
+ K K * 0 L . [pop] [Fw] while popopd
+ K K * 0 L [pop] . [Fw] while popopd
+ K K * 0 L [pop] [Fw] . while popopd
+ ^^^^^
+ K K * 0 L . popopd
+ L .
So:
::
- K == u dup * dup *
- L == K u *
+ K == u dup * dup *
+ L == K u *
-Our result "thunk" would be:
+Our result “thunk” would be:
::
- u dup * dup * u *
+ u dup * dup * u *
Mechanically, you could do:
::
- u dup * dup * u *
- u u [dup * dup *] dip *
- u dup [dup * dup *] dip *
+ u dup * dup * u *
+ u u [dup * dup *] dip *
+ u dup [dup * dup *] dip *
- F5 == dup [dup * dup *] dip *
+ F5 == dup [dup * dup *] dip *
But we can swap the two arguments to the final ``*`` to get all mentions
of ``u`` to the left:
::
- u u dup * dup * *
+ u u dup * dup * *
-Then de-duplicate "u":
+Then de-duplicate “u”:
::
- u dup dup * dup * *
+ u dup dup * dup * *
To arrive at a startlingly elegant form for F5:
::
- F5 == dup dup * dup * *
+ F5 == dup dup * dup * *
.. code:: ipython2
-I'm not sure how to implement these kinds of thunks. I think you have to
+I’m not sure how to implement these kinds of thunks. I think you have to
have support in the interpreter, or you have to modify all of the
functions like ``dup`` to check for thunks in their inputs.
::
- dup dup * dup * *
+ dup dup * dup * *
We can already generate:
::
- ---------------------------------
- (a0, stack) = stack
- a1 = mul(a0, a0)
- a2 = mul(a1, a1)
- a3 = mul(a2, a0)
- stack = (a3, stack)
- ---------------------------------
+ ---------------------------------
+ (a0, stack) = stack
+ a1 = mul(a0, a0)
+ a2 = mul(a1, a1)
+ a3 = mul(a2, a0)
+ stack = (a3, stack)
+ ---------------------------------
-This is pretty old stuff... (E.g. from 1999, M. Anton Ertl `Compilation
-of Stack-Based
+This is pretty old stuff… (E.g. from 1999, M. Anton Ertl `Compilation of
+Stack-Based
Languages <http://www.complang.tuwien.ac.at/projects/rafts.html>`__ he
goes a lot further for Forth.)
-"A Transformation Based Approach to Semantics-Directed Code Generation"
+“A Transformation Based Approach to Semantics-Directed Code Generation”
-----------------------------------------------------------------------
by Arthur Nunes-Harwitt
::
- m == [*] cons
+ m == [*] cons
- 3 2 m i
- 3 2 [*] cons i
- 3 [2 *] i
- 3 2 *
- 6
+ 3 2 m i
+ 3 2 [*] cons i
+ 3 [2 *] i
+ 3 2 *
+ 6
.. code:: ipython2
::
- p == [0 =] [popop 1] [-- over] [dip *] genrec
+ p == [0 =] [popop 1] [-- over] [dip *] genrec
- b n p
- b n [0 =] [popop 1] [-- over [p] dip *]
+ b n p
+ b n [0 =] [popop 1] [-- over [p] dip *]
- b n -- over [p] dip *
- b n-1 over [p] dip *
- b n-1 b [p] dip *
- b n-1 p b *
+ b n -- over [p] dip *
+ b n-1 over [p] dip *
+ b n-1 b [p] dip *
+ b n-1 p b *
curried, quoted
::
- n p
- ---------------------------------------------
- [[n 0 =] [pop 1] [dup n --] [*] genrec]
+ n p
+ ---------------------------------------------
+ [[n 0 =] [pop 1] [dup n --] [*] genrec]
.. code:: ipython2
::
- p == [0 =] [[pop 1]] [ [-- [dup] dip p *] cons ]ifte
+ p == [0 =] [[pop 1]] [ [-- [dup] dip p *] cons ]ifte
- 3 p
- 3 [-- [dup] dip p *] cons
- [3 -- [dup] dip p *]
+ 3 p
+ 3 [-- [dup] dip p *] cons
+ [3 -- [dup] dip p *]
.. code:: ipython2
::
- p == [0 =] [pop [pop 1]] [-- p [dupdip *] cons] ifte
+ p == [0 =] [pop [pop 1]] [-- p [dupdip *] cons] ifte
- 3 p
- 3 -- p [dupdip *] cons
- 2 p [dupdip *] cons
- 2 -- p [dupdip *] cons [dupdip *] cons
- 1 p [dupdip *] cons [dupdip *] cons
- 1 -- p [dupdip *] cons [dupdip *] cons [dupdip *] cons
- 0 p [dupdip *] cons [dupdip *] cons [dupdip *] cons
- 0 pop [pop 1] [dupdip *] cons [dupdip *] cons [dupdip *] cons
- [pop 1] [dupdip *] cons [dupdip *] cons [dupdip *] cons
- ...
- [[[[pop 1] dupdip *] dupdip *] dupdip *]
+ 3 p
+ 3 -- p [dupdip *] cons
+ 2 p [dupdip *] cons
+ 2 -- p [dupdip *] cons [dupdip *] cons
+ 1 p [dupdip *] cons [dupdip *] cons
+ 1 -- p [dupdip *] cons [dupdip *] cons [dupdip *] cons
+ 0 p [dupdip *] cons [dupdip *] cons [dupdip *] cons
+ 0 pop [pop 1] [dupdip *] cons [dupdip *] cons [dupdip *] cons
+ [pop 1] [dupdip *] cons [dupdip *] cons [dupdip *] cons
+ ...
+ [[[[pop 1] dupdip *] dupdip *] dupdip *]
- 2 [[[[pop 1] dupdip *] dupdip *] dupdip *] i
- 2 [[[pop 1] dupdip *] dupdip *] dupdip *
- 2 [[pop 1] dupdip *] dupdip * 2 *
- 2 [pop 1] dupdip * 2 * 2 *
- 2 pop 1 2 * 2 * 2 *
- 1 2 * 2 * 2 *
+ 2 [[[[pop 1] dupdip *] dupdip *] dupdip *] i
+ 2 [[[pop 1] dupdip *] dupdip *] dupdip *
+ 2 [[pop 1] dupdip *] dupdip * 2 *
+ 2 [pop 1] dupdip * 2 * 2 *
+ 2 pop 1 2 * 2 * 2 *
+ 1 2 * 2 * 2 *
- p == [0 =] [pop [pop 1]] [-- p [dupdip *] cons] ifte
- p == [0 =] [pop [pop 1]] [-- [p] i [dupdip *] cons] ifte
- p == [0 =] [pop [pop 1]] [--] [i [dupdip *] cons] genrec
+ p == [0 =] [pop [pop 1]] [-- p [dupdip *] cons] ifte
+ p == [0 =] [pop [pop 1]] [-- [p] i [dupdip *] cons] ifte
+ p == [0 =] [pop [pop 1]] [--] [i [dupdip *] cons] genrec
.. code:: ipython2
::
- p == [0 =] [pop pop 1] [-- over] [dip *] genrec
+ p == [0 =] [pop pop 1] [-- over] [dip *] genrec
To this:
::
- p == [0 =] [pop [pop 1]] [--] [i [dupdip *] cons] genrec
+ p == [0 =] [pop [pop 1]] [--] [i [dupdip *] cons] genrec
Try it with ``F()``:
--------------------
print source
eval(source)(2)
-Hmm...
+Hmm…
.. code:: ipython2
So that gets pretty good, eh?
-But looking back at the definition in Joy, it doesn't seem easy to
+But looking back at the definition in Joy, it doesn’t seem easy to
directly apply this technique to Joy code:
::
- Ft == [over] dip *
- Fb == [[sqr] dip 2 //] dip
- Fw == [pop odd] [Ft] [] ifte Fb
- F == 1 [pop] [Fw] while popopd
+ Ft == [over] dip *
+ Fb == [[sqr] dip 2 //] dip
+ Fw == [pop odd] [Ft] [] ifte Fb
+ F == 1 [pop] [Fw] while popopd
But a direct translation of the Python code..?
::
- F == [
- [[0 =] [pop 1]]
- [[1 =] []]
- [_F.0]
- ] cond
+ F == [
+ [[0 =] [pop 1]]
+ [[1 =] []]
+ [_F.0]
+ ] cond
- _F.0 == dup 2 // [
- [[0 =] [pop 1]]
- [[pop odd] _F.1]
- [_F.2]
- ] cond
+ _F.0 == dup 2 // [
+ [[0 =] [pop 1]]
+ [[pop odd] _F.1]
+ [_F.2]
+ ] cond
- _F.1 == [1 =] [pop [dup dup * *]] [popd F [dupdip over * *] cons] ifte
- _F.2 == [1 =] [pop [dup *]] [popd F [i dup *] cons] ifte
+ _F.1 == [1 =] [pop [dup dup * *]] [popd F [dupdip over * *] cons] ifte
+ _F.2 == [1 =] [pop [dup *]] [popd F [i dup *] cons] ifte
Try it:
::
- 5 F
- 5 [ [[0 =] [pop 1]] [[1 =] []] [_F.0] ] cond
- 5 _F.0
- 5 dup 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
- 5 5 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
+ 5 F
+ 5 [ [[0 =] [pop 1]] [[1 =] []] [_F.0] ] cond
+ 5 _F.0
+ 5 dup 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
+ 5 5 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
- 5 2 [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
- 5 2 _F.1
- 5 2 [1 =] [popop [dup dup * *]] [popd F [dupdip over * *] cons] ifte
- 5 2 popd F [dupdip over * *] cons
- 2 F [dupdip over * *] cons
+ 5 2 [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
+ 5 2 _F.1
+ 5 2 [1 =] [popop [dup dup * *]] [popd F [dupdip over * *] cons] ifte
+ 5 2 popd F [dupdip over * *] cons
+ 2 F [dupdip over * *] cons
- 2 F [dupdip over * *] cons
+ 2 F [dupdip over * *] cons
- 2 F
- 2 [ [[0 =] [pop 1]] [[1 =] []] [_F.0] ] cond
- 2 _F.0
- 2 dup 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
- 2 2 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
- 2 1 [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
- 2 1 _F.2
- 2 1 [1 =] [popop [dup *]] [popd F [i dup *] cons] ifte
- 2 1 popop [dup *]
- [dup *]
+ 2 F
+ 2 [ [[0 =] [pop 1]] [[1 =] []] [_F.0] ] cond
+ 2 _F.0
+ 2 dup 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
+ 2 2 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
+ 2 1 [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
+ 2 1 _F.2
+ 2 1 [1 =] [popop [dup *]] [popd F [i dup *] cons] ifte
+ 2 1 popop [dup *]
+ [dup *]
- 2 F [dupdip over * *] cons
- [dup *] [dupdip over * *] cons
- [[dup *] dupdip over * *]
+ 2 F [dupdip over * *] cons
+ [dup *] [dupdip over * *] cons
+ [[dup *] dupdip over * *]
And here it is in action:
::
- 2 [[dup *] dupdip over * *] i
- 2 [dup *] dupdip over * *
- 2 dup * 2 over * *
- 2 2 * 2 over * *
- 4 2 over * *
- 4 2 4 * *
- 4 8 *
- 32
+ 2 [[dup *] dupdip over * *] i
+ 2 [dup *] dupdip over * *
+ 2 dup * 2 over * *
+ 2 2 * 2 over * *
+ 4 2 over * *
+ 4 2 4 * *
+ 4 8 *
+ 32
So, it works, but in this case the results of the partial evaluation are
more elegant.
Given some text describing a Joy function definition parse it and
return a DefinitionWrapper.
'''
- return class_(*(n.strip() for n in defi.split(maxsplit=1)))
+ return class_(*(n.strip() for n in defi.split(None, 1)))
@classmethod
def add_definitions(class_, defs, dictionary):