Rebuild docs

This commit is contained in:
Simon Forman 2020-05-17 16:40:58 -07:00
parent ef6411205d
commit 56da4690d0
84 changed files with 7456 additions and 7972 deletions

View File

@ -22,18 +22,18 @@ that you start by running the package:
::
$ python -m joy
Joypy - Copyright © 2017 Simon Forman
This program comes with ABSOLUTELY NO WARRANTY; for details type "warranty".
This is free software, and you are welcome to redistribute it
under certain conditions; type "sharing" for details.
Type "words" to see a list of all words, and "[<name>] help" to print the
docs for a word.
$ 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
@ -42,18 +42,18 @@ and prompt again:
::
joy? 23 sqr 18 +
. 23 sqr 18 +
23 . sqr 18 +
23 . dup mul 18 +
23 23 . mul 18 +
529 . 18 +
529 18 . +
547 .
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.)
========================================
@ -103,8 +103,8 @@ Purely Functional Datastructures.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Because Joy lists are made out of Python tuples they are immutable, so
all Joy datastructures are *`purely
functional <https://en.wikipedia.org/wiki/Purely_functional_data_structure>`__*.
all Joy datastructures are `purely
functional <https://en.wikipedia.org/wiki/Purely_functional_data_structure>`__.
The ``joy()`` function.
=======================
@ -119,8 +119,8 @@ looks up in the dictionary.
Each function is passed the stack, expression, and dictionary and
returns them. Whatever the function returns becomes the new stack,
expression, and dictionary. (The dictionary is passed to enable e.g.
writing words that let you enter new words into the dictionary at
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.)
@ -133,7 +133,7 @@ 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
@ -147,7 +147,7 @@ A ``viewer`` records each step of the evaluation of a Joy program. The
``TracePrinter`` has a facility for printing out a trace of the
evaluation, one line per step. Each step is aligned to the current
interpreter position, signified by a period separating the stack on the
left from the pending expression ("continuation") on the right.
left from the pending expression (“continuation”) on the right.
`Continuation-Passing Style <https://en.wikipedia.org/wiki/Continuation-passing_style>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -191,7 +191,7 @@ Parser
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. Theres no Abstract Syntax Tree or anything
like that.
.. code:: ipython2
@ -226,7 +226,7 @@ like that.
That's pretty much all there is to it.
Thats pretty much all there is to it.
.. code:: ipython2
@ -298,7 +298,7 @@ That's pretty much all there is to it.
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
@ -398,42 +398,42 @@ continuation) and returns control to the interpreter.
Currently, there's no function to add new definitions to the dictionary
from "within" Joy code itself. Adding new definitions remains a
Currently, theres no function to add new definitions to the dictionary
from “within” Joy code itself. Adding new definitions remains a
meta-interpreter action. You have to do it yourself, in Python, and wash
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. Theres 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, thats 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 shouldnt be dozens of chat apps, JS
frameworks, programming languages. Its 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 youll 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

View File

@ -58,7 +58,7 @@ A ``viewer`` records each step of the evaluation of a Joy program. The
``TracePrinter`` has a facility for printing out a trace of the
evaluation, one line per step. Each step is aligned to the current
interpreter position, signified by a period separating the stack on the
left from the pending expression ("continuation") on the right. I find
left from the pending expression (“continuation”) on the right. I find
these traces beautiful, like a kind of art.
.. code:: ipython2
@ -105,7 +105,7 @@ these traces beautiful, like a kind of art.
15 .
Here's a longer trace.
Heres a longer trace.
.. code:: ipython2

View File

@ -10,10 +10,10 @@ Stack Chatter
This is what I like to call the functions that just rearrange things on
the stack. (One thing I want to mention is that during a hypothetical
compilation phase these "stack chatter" words effectively disappear,
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.)
its “off the shelf” technology.)
``clear``
~~~~~~~~~
@ -139,7 +139,7 @@ they are not, is on the top of both the list and the stack.
``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
@ -474,7 +474,7 @@ List words
``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.
@ -869,7 +869,7 @@ pow
~~~~~~~~~~~~~~~~~~
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
@ -931,7 +931,7 @@ Get the Boolean value of the item on the top of the stack.
::
? == dup truthy
? == dup truthy
.. code:: ipython2
@ -1178,15 +1178,15 @@ function ``[G]``, the ``anamorphism`` combinator creates a sequence.
::
n [P] [G] anamorphism
---------------------------
[...]
n [P] [G] anamorphism
---------------------------
[...]
Example, ``range``:
::
range == [0 <=] [1 - dup] anamorphism
range == [0 <=] [1 - dup] anamorphism
.. code:: ipython2
@ -1226,25 +1226,25 @@ Example, ``range``:
::
... 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
@ -1297,7 +1297,7 @@ Expects a quoted program ``[Q]`` on the stack and some item under it,
::
n [Q] dupdip == n Q n
n [Q] dupdip == n Q n
.. code:: ipython2
@ -1417,7 +1417,7 @@ Expects a quoted program ``[Q]`` on the stack and some item under it,
::
[predicate] [then] [else] ifte
[predicate] [then] [else] ifte
.. code:: ipython2
@ -1724,7 +1724,7 @@ Run a quoted program enforcing
::
[predicate] [body] while
[predicate] [body] while
.. code:: ipython2
@ -1784,8 +1784,8 @@ Run a quoted program enforcing
``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.)

View File

@ -1,17 +1,17 @@
`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
Lets create a predicate that returns ``True`` if a number is a multiple
of 3 or 5 and ``False`` otherwise.
.. code:: ipython2
@ -44,7 +44,7 @@ Given the predicate function ``P`` a suitable program is:
::
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.
@ -68,22 +68,22 @@ Consider the first few terms in the series:
::
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.
@ -95,7 +95,7 @@ the counter to the running sum. This function will do that:
::
PE1.1 == + [+] dupdip
PE1.1 == + [+] dupdip
.. code:: ipython2
@ -276,8 +276,8 @@ get to 990 and then the first four numbers 3 2 1 3 to get to 999.
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. Its
good but theres 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
@ -286,8 +286,8 @@ integer terms from the list.
::
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
@ -516,14 +516,14 @@ And so we have at last:
233168
Let's refactor.
Lets 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
@ -545,21 +545,21 @@ Now we can simplify the definition above:
233168
Here's our joy program all in one place. It doesn't make so much sense,
Heres our joy program all in one place. It doesnt 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 its 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
Its 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.
@ -591,8 +591,8 @@ terms to reach up to but not over one thousand.
466
Here they are...
~~~~~~~~~~~~~~~~
Here they are
~~~~~~~~~~~~~~
.. code:: ipython2
@ -604,8 +604,8 @@ Here they are...
3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 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
@ -618,7 +618,7 @@ Here they are...
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 were done,
leaving just the sum.
.. code:: ipython2
@ -652,21 +652,21 @@ Instead of summing them,
::
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, Ill leave that to you if
you want to work it out or you can take my word for it.)
.. code:: ipython2
@ -695,20 +695,20 @@ Generalizing to Blocks of Terms
We can apply the same reasoning to the PE1 problem.
Between 0 and 990 inclusive there are sixty-six "blocks" of seven terms
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
@ -749,9 +749,9 @@ additional unpaired terms between 990 and 1000:
::
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
@ -764,7 +764,7 @@ so:
233168
It's worth noting, I think, that this same reasoning holds for any two
Its 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.
@ -774,14 +774,14 @@ interval spanning the least common multiple of :math:`n` and :math:`m`:
::
| | | | | | | |
| | | | |
| | | | | | | |
| | | | |
Here we have 4 and 7, and you can read off the sequence of differences
directly from the diagram: 4 3 1 4 2 2 4 1 3 4.
Geometrically, the actual values of :math:`n` and :math:`m` and their
*lcm* don't matter, the pattern they make will always be symmetrical
*lcm* dont matter, the pattern they make will always be symmetrical
around its midpoint. The same reasoning holds for multiples of more than
two numbers.
@ -793,6 +793,6 @@ is just:
::
PE1 == 233168
PE1 == 233168
Fin.

View File

@ -21,7 +21,7 @@ For example:
from notebook_preamble import J, V, define
I'll assume the input is a Joy sequence of integers (as opposed to a
Ill 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
@ -31,26 +31,26 @@ a total if the pair matches.
::
AoC2017.1 == pair_up total_matches
AoC2017.1 == pair_up total_matches
Let's derive ``pair_up``:
Lets 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 doesnt 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
@ -80,40 +80,40 @@ Now we need to derive ``total_matches``. It will be a ``step`` function:
::
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
@ -197,17 +197,17 @@ Now we can define our main program and evaluate it on the examples.
::
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
@ -219,7 +219,7 @@ Now the paired digit is "halfway" round.
[[3 1] [4 2] [1 3] [2 4]]
I realized that each pair is repeated...
I realized that each pair is repeated
.. code:: ipython2
@ -270,19 +270,19 @@ Refactor FTW
With Joy a great deal of the heuristics from Forth programming carry
over nicely. For example, refactoring into small, well-scoped commands
with mnemonic names...
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 *

View File

@ -11,35 +11,35 @@ For example, given the following spreadsheet:
::
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 rows 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 rows largest and smallest values are 7 and 3, and their
difference is 4.
- The third row's difference is 6.
- The third rows difference is 6.
In this example, the spreadsheet's checksum would be 8 + 4 + 6 = 18.
In this example, the spreadsheets 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.
Ill 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
@ -63,7 +63,7 @@ Then ``F`` just does that then subtracts the min from the max:
::
F == maxmin -
F == maxmin -
So:
@ -87,18 +87,18 @@ 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 lines 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.
@ -107,7 +107,7 @@ For example, given the following spreadsheet:
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 rows result in your puzzle input?
.. code:: ipython2
@ -131,8 +131,8 @@ What is the sum of each row's result in your puzzle input?
::
[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
@ -162,7 +162,7 @@ What is the sum of each row's result in your puzzle input?
Tricky
------
Let's think.
Lets 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
@ -173,62 +173,62 @@ So we want a ``loop`` I think
::
[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 dont 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
@ -244,55 +244,55 @@ Now we just have to ``pop`` it if we don't need it.
::
[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.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -302,36 +302,36 @@ candidates and return the result or zero:
::
n [...] G
---------------
result
n [...] G
---------------
result
n [...] G
---------------
0
n [...] G
---------------
0
It's a recursive function that conditionally executes the recursive part
Its 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.
@ -339,8 +339,8 @@ Otherwise, we have:
::
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``.
@ -350,16 +350,16 @@ 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. Its 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
@ -367,20 +367,20 @@ consumed by ``G``.)
::
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
@ -402,7 +402,7 @@ guard the ``uncons``.
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

View File

@ -13,11 +13,11 @@ example, the first few squares are allocated like this:
::
17 16 15 14 13
18 5 4 3 12
19 6 1 2 11
20 7 8 9 10
21 22 23---> ...
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
@ -27,7 +27,7 @@ Distance between the location of the data and square 1.
For example:
- Data from square 1 is carried 0 steps, since it's at the access port.
- Data from square 1 is carried 0 steps, since its 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.
@ -39,8 +39,8 @@ Analysis
~~~~~~~~
I freely admit that I worked out the program I wanted to write using
graph paper and some Python doodles. There's no point in trying to write
a Joy program until I'm sure I understand the problem well enough.
graph paper and some Python doodles. Theres no point in trying to write
a Joy program until Im 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
@ -48,61 +48,61 @@ patterns directly:
::
1 0
2 1
3 2
4 1
5 2
6 1
7 2
8 1
9 2
10 3
11 2
12 3
13 4
14 3
15 2
16 3
17 4
18 3
19 2
20 3
21 4
22 3
23 2
24 3
25 4
26 5
27 4
28 3
29 4
30 5
31 6
32 5
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
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`
@ -115,15 +115,15 @@ This shows that the series consists at each place of :math:`k` plus some
number that begins at :math:`k - 1`, decreases to zero, then increases
to :math:`k`. Each row has :math:`2k` members.
Let's figure out how, given an index into a row, we can calculate the
Lets 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`:
Lets 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
@ -156,7 +156,7 @@ value:
3 2 1 0 1 2 3 4
Great, now add :math:`k`...
Great, now add :math:`k`\ …
.. code:: ipython2
@ -190,7 +190,7 @@ index:
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
(Im 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.)
@ -209,8 +209,8 @@ initial square we have:
:math:`corner_k = 1 + \sum_{n=1}^k 8n`
I'm not mathematically sophisticated enough to turn this directly into a
formula (but Sympy is, see below.) I'm going to write a simple Python
Im not mathematically sophisticated enough to turn this directly into a
formula (but Sympy is, see below.) Im going to write a simple Python
function to iterate and search:
.. code:: ipython2
@ -420,7 +420,7 @@ Sympy to the Rescue
Find the rank for large numbers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using e.g. Sympy we can find the rank directly by solving for the roots
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.
@ -459,7 +459,7 @@ We want:
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
@ -472,7 +472,7 @@ about the larger one we use ``max()`` to select it. It will generally
not be a nice integer (unless :math:`n` is the number of an end-corner
of a rank) so we take the ``floor()`` and add 1 to get the integer rank
of :math:`n`. (Taking the ``ceiling()`` gives off-by-one errors on the
rank boundaries. I don't know why. I'm basically like a monkey doing
rank boundaries. I dont know why. Im basically like a monkey doing
math here.) =-D
It gives correct answers:
@ -534,7 +534,7 @@ And it runs much faster (at least for large numbers):
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 ranks 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.
@ -542,8 +542,8 @@ is partially shared by the other method, and overshadowed by the time it
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)
@ -558,7 +558,7 @@ and ask it to solve for :math:`k`.
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
@ -622,7 +622,7 @@ to get a Python function that calculates the rank directly.
50 4
It's pretty fast.
Its pretty fast.
.. code:: ipython2
@ -685,7 +685,7 @@ compute the offset into a pyramid row.
(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 ranks 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)`.)
@ -797,17 +797,17 @@ this code in Joy. ;-)
::
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
@ -818,36 +818,36 @@ The translation is straightforward.
::
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
@ -858,18 +858,18 @@ Ergo:
::
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
@ -880,16 +880,16 @@ Ergo:
::
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
@ -965,8 +965,8 @@ Ergo:
::
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

View File

@ -12,30 +12,30 @@ For example:
- 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 systems 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.
Ill 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:
@ -53,7 +53,7 @@ open one of these definitions:
::
AoC2017.4 == [F +] step_zero
AoC2017.4 == [F +] step_zero
.. code:: ipython2

View File

@ -4,7 +4,7 @@ Advent of Code 2017
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.
@ -18,13 +18,13 @@ For example, consider the following list of jump offsets:
::
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:
@ -35,14 +35,24 @@ 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, dont 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.
@ -51,7 +61,7 @@ How many steps does it take to reach the exit?
Breakdown
---------
For now, I'm going to assume a starting state with the size of the
For now, Im 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
@ -59,66 +69,66 @@ itself, and some recursive function ``F`` that does the work.
::
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``! Doh!
::
index step-count [...] F
------------------------------
step-count
index step-count [...] F
------------------------------
step-count
So, let's start by nailing down the predicate:
So, lets 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 wouldnt beat the
performance of e.g. a mutable array. This is just one of those places
where “plain vanilla” Joypy doesnt 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, Im going to write a primitive function that just does
what we need.
.. code:: ipython2
@ -166,52 +176,52 @@ get the value at index
::
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
@ -250,9 +260,9 @@ We want to go from this to this:
::
[...] AoC2017.5.preamble
------------------------------
0 0 [...] [popop n >=]
[...] AoC2017.5.preamble
------------------------------
0 0 [...] [popop n >=]
Where ``n`` is the size of the sequence.
@ -260,23 +270,23 @@ The first part is obviously ``0 0 roll<``, then ``dup size``:
::
[...] 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
@ -303,21 +313,21 @@ So:
::
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 wouldnt be as efficient as something written in assembly, C, or
even Python.

View File

@ -6,7 +6,7 @@ December 6th
::
[0 2 7 0] dup max
[0 2 7 0] dup max
.. code:: ipython2
@ -77,16 +77,16 @@ December 6th
-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
@ -168,25 +168,25 @@ This seems like it would be a PITA to implement in Joypy...
[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
@ -217,53 +217,53 @@ First draft:
::
[] [GEN] x [pop index_of 0 >=] [pop size --] [[swons] dip x] primrec
[] [GEN] x [pop index_of 0 >=] [pop size --] [[swons] dip x] primrec
(?)
::
[] [GEN] 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

View File

@ -9,7 +9,7 @@ Given a Joy program like:
::
sqr == dup mul
sqr == dup mul
.. code:: ipython2
@ -58,7 +58,7 @@ The simplest thing would be to compose the functions from the library:
529 .
It's simple to write a function to emit this kind of crude "compiled"
Its simple to write a function to emit this kind of crude “compiled”
code.
.. code:: ipython2
@ -96,7 +96,7 @@ But what about literals?
::
quoted == [unit] dip
quoted == [unit] dip
.. code:: ipython2
@ -126,10 +126,10 @@ Compiling Yin Functions
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.
@ -162,7 +162,7 @@ loop.
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
@ -205,16 +205,16 @@ new stack structure.
Compiling from Stack Effects
----------------------------
There are times when you're deriving a Joy program when you have a stack
There are times when youre 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
@ -222,11 +222,11 @@ stack effect:
::
[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 havent yet implemented a simple interface for this yet. What follow
is an exploration of how to do it.)
.. code:: ipython2
@ -373,7 +373,7 @@ Now we can omit ``a3`` and ``a4`` if we like:
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 nodes stack/list.
.. code:: ipython2
@ -404,7 +404,7 @@ subsumed in the tail of the node's stack/list.
return ((a1, (a5, s1)), s0)
Oops! The input stack is backwards...
Oops! The input stack is backwards
.. code:: ipython2
@ -443,9 +443,9 @@ Compare:
::
[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
@ -510,7 +510,7 @@ Then we would want something like this:
How about...
How about
.. code:: ipython2
@ -561,7 +561,7 @@ How about...
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. Im going to reuse
``Symbol`` class for this.
.. code:: ipython2
@ -579,7 +579,7 @@ First, we need a source of Python identifiers. I'm going to reuse
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 (well implement other kinds a little later.)
.. code:: ipython2
@ -594,7 +594,7 @@ args and return one result (we'll implement other kinds a little later.)
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
@ -676,7 +676,7 @@ Something to convert the graph into Python code.
''' % (name, code_gen(I((), expression, [])))
A few functions to try it with...
A few functions to try it with
.. code:: ipython2
@ -706,7 +706,7 @@ A few functions to try it with...
def import_yin():
... and there we are.
… and there we are.
.. code:: ipython2

View File

@ -14,8 +14,8 @@ Expressions ○ SAT Solver ○ A Model of Computation
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
@ -31,21 +31,21 @@ Arithmetic
::
(()) =
()() = ()
(()) =
()() = ()
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
@ -56,8 +56,8 @@ Python Sets and Strings as Laws of Form Calculus Expressions
------------------------------------------------------------
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. Im
going to use the terms “expression” and “form” interchangably in this
document.
.. code:: ipython2
@ -167,7 +167,7 @@ Order is irrelevant, again due to ``frozenset``.
It's prefectly okay to create forms out of other forms (not just
Its prefectly okay to create forms out of other forms (not just
strings.)
.. code:: ipython2
@ -266,7 +266,7 @@ Once the forms have been rendered to pure arithmetic we can use the
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 lets write a function that returns the Mark
or Void value of a form.
.. code:: ipython2
@ -334,7 +334,7 @@ can evaluate an expression containing those names and compute its value.
This is a bit hard to read, so let's define a helper function to convert
This is a bit hard to read, so lets define a helper function to convert
an environment to a string format.
.. code:: ipython2
@ -373,7 +373,7 @@ just like a list of the eight three-bit binary numbers.
Reify the Forms with Each Meaning
---------------------------------
Let's pick one of the expressions and iterate through the environments
Lets pick one of the expressions and iterate through the environments
showing the result of reifying that expression in that environment.
.. code:: ipython2
@ -402,7 +402,7 @@ showing the result of reifying that expression in that environment.
Truth Table
-----------
Let's render the above as a `Truth
Lets render the above as a `Truth
Table <https://en.wikipedia.org/wiki/Truth_table>`__.
.. code:: ipython2
@ -437,17 +437,17 @@ Table <https://en.wikipedia.org/wiki/Truth_table>`__.
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
Lets build Circuits
====================
In order to work with expressions as digital circuits, let's define some
In order to work with expressions as digital circuits, lets 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>`__.
@ -502,7 +502,7 @@ Some examples:
((((((((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 lets rewrite the ``truth_table_3()`` function to make it work for
any number of variables.
.. code:: ipython2
@ -678,27 +678,27 @@ This is a
`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 doesnt even bother to stop once its 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 didnt just create the expression for this table:
::
a b c | Value
---------+------
|
() |
() |
() () | ()
() |
() () | ()
() () | ()
() () () |
a b c | Value
---------+------
|
() |
() |
() () | ()
() |
() () | ()
() () | ()
() () () |
Each Row can be Represented as an Expression
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -708,17 +708,17 @@ 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, lets
look at the sixth expression above:
.. code:: ipython2
@ -743,26 +743,26 @@ look at the sixth expression above:
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:
@ -800,13 +800,13 @@ E1 that has the same truth table, in other words:
::
((((((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.
@ -844,23 +844,23 @@ that the expression is a **tautology**.
`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, its easy to see that the carry bit is just **AND** and the
sum bit is just **XOR** of the two input bits.
.. code:: ipython2
@ -911,36 +911,36 @@ together and a carry bit from the previous addition:
::
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
@ -985,7 +985,7 @@ We can easily determine expressions for sum and carry:
() () () | ()
Let's make a ``full_bit_adder()`` function that can define new
Lets make a ``full_bit_adder()`` function that can define new
expressions in terms of variables (or expressions) passed into it.
.. code:: ipython2
@ -1033,8 +1033,8 @@ article <https://en.wikipedia.org/wiki/Adder_%28electronics%29#Full_adder>`__:
::
S = A ⊕ B ⊕ C
Cout = (A ⋅ B) + (Cin ⋅ (A ⊕ B))
S = A ⊕ B ⊕ C
Cout = (A ⋅ B) + (Cin ⋅ (A ⊕ B))
.. code:: ipython2
@ -1122,11 +1122,11 @@ rules of the calculus automatically:
::
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
Im going to specify the behaviour of the desired function in a
unittest.
.. code:: ipython2
@ -1136,7 +1136,7 @@ unittest.
Three Easy Cases
~~~~~~~~~~~~~~~~
Let's deal with three easy cases first: string, the Mark, and the Void.
Lets deal with three easy cases first: string, the Mark, and the Void.
The ``simplify()`` function should just return them unchanged.
.. code:: ipython2
@ -1216,7 +1216,7 @@ Doubly-Wrapped Forms
~~~~~~~~~~~~~~~~~~~~
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 cant
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.)
@ -1330,7 +1330,7 @@ Does it work for ``(((a))) = (a)`` and ``((((a)))) = a`` and so on?
Unwrapping Inner Forms
~~~~~~~~~~~~~~~~~~~~~~
But now let's trick our function, it can't handle
But now lets trick our function, it cant 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.
@ -1639,7 +1639,7 @@ So we have ``(()) = --`` and ``()A = ()`` what about ``A(AB) = A(B)``?
TODO set up `Hypothesis <http://hypothesis.works/>`__ to generate test
cases...
cases
.. code:: ipython2
@ -1658,14 +1658,14 @@ cases...
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
@ -1683,8 +1683,8 @@ GSB called this "Each-Way":
() () | ()
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”. Ill 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
@ -1695,20 +1695,20 @@ next to it
::
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
@ -2004,7 +2004,7 @@ each. Try the following cells with both versions of the ``Sum`` and
(((((b) a) (b)) c) ((c) a b))
Let's redefine the ``full_bit_adder()`` function with the smallest
Lets redefine the ``full_bit_adder()`` function with the smallest
version of each above.
.. code:: ipython2
@ -2103,8 +2103,8 @@ other two.
`DavisPutnamLogemannLoveland (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 arent going to use it below, but
its 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.
@ -2113,7 +2113,7 @@ It works by selecting a name from the form, and simplifying the form
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.
@ -2329,7 +2329,7 @@ solutions after the first.
{'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 doesnt
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.
@ -2350,11 +2350,11 @@ The form ``(((a5) a5))`` is Mark-valued:
::
(((a5) a5))
((( ) a5))
((( ) ))
( )
()
(((a5) a5))
((( ) a5))
((( ) ))
( )
()
.. code:: ipython2
@ -2377,7 +2377,7 @@ Now back to Circuits
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 Im going to use just four bits rather
than eight.
.. code:: ipython2
@ -2948,18 +2948,18 @@ arranged to make it (relatively) easy to see the addition.
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, lets formalize it and make it a little easier to
work with.
First let's have a *register* of named values:
First lets 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
Lets 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
@ -2983,7 +2983,7 @@ the program with the current values in the register.
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
@ -3008,7 +3008,7 @@ With all the register values at "zero" (Void) nothing happens.
Let's make a nice display function to inspect our little adder computer.
Lets make a nice display function to inspect our little adder computer.
.. code:: ipython2
@ -3050,7 +3050,7 @@ Let's make a nice display function to inspect our little adder computer.
a: 0 b: 0 Cin: 0 Cout: 0
Let's set one bit to true (Mark-valued in the chosen convention. We
Lets 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.)
@ -3058,7 +3058,7 @@ expressions differently.)
R['a0'] = Mark
Now let's count to twenty.
Now lets count to twenty.
.. code:: ipython2
@ -3092,7 +3092,7 @@ Now let's count to twenty.
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
@ -3133,12 +3133,12 @@ the count cycles back to zero.
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 isnt
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.
@ -3285,7 +3285,7 @@ Simple One-Dimensional Cellular Automaton
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
@ -3334,7 +3334,7 @@ Void-valued.
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 Ps expressions with the marks in R.
.. code:: ipython2
@ -3489,8 +3489,8 @@ evaluated by solving P's expressions with the marks in R.
return i
return inner
Each-Way as If... Then...
~~~~~~~~~~~~~~~~~~~~~~~~~
Each-Way as If… Then…
~~~~~~~~~~~~~~~~~~~~~
.. code:: ipython2
@ -3528,21 +3528,21 @@ but if ``a`` is Void-valued the value of the whole form is that of
::
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
---------------------
@ -3572,32 +3572,32 @@ 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:
@ -3700,8 +3700,8 @@ 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.
@ -3717,7 +3717,7 @@ 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
Well assume a single ``WRITE`` bit that sets a RAM location determined
by the ``ADDR`` sub-register to the contents of the ``DATA``
sub-register.
@ -4039,47 +4039,47 @@ w/ A = ()
::
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
---------------------------------------------------
@ -4195,7 +4195,7 @@ terms of each other. Note that ``void()`` uses ``any()`` while
``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 termss results so its runtime
will be bound by term with the greatest runtime.
.. code:: ipython2
@ -4243,22 +4243,22 @@ Consider:
::
(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
@ -4273,32 +4273,32 @@ original statement:
::
¬((¬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
@ -4351,7 +4351,7 @@ Misc. Junk
# 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()`` lets 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
@ -4441,7 +4441,7 @@ It would be useful and fun to write a simple search algorithm that tried
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
Lets generate the expressions for the next two output bits, and the
carry bit.
The ``sum3`` bit expression is pretty big.
@ -4450,7 +4450,7 @@ The ``sum3`` bit expression is pretty big.
sum3
But it's only about 1/9th of size of the previous version (which was
But its only about 1/9th of size of the previous version (which was
9261.)
.. code:: ipython2
@ -4463,13 +4463,13 @@ But it's only about 1/9th of size of the previous version (which was
Let's simplify the first one manually just for fun:
Lets 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,
@ -4478,9 +4478,9 @@ original expression:
::
((((a)b)(c)))
(( ) )( )
( )
((((a)b)(c)))
(( ) )( )
( )
.. code:: ipython2
@ -4552,7 +4552,7 @@ expression.
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.
Lets try using ``each_way()`` with the most common names in the form.
.. code:: ipython2

View File

@ -1,69 +1,69 @@
∂RE
===
Brzozowski's Derivatives of Regular Expressions
Brzozowskis Derivatives of Regular Expressions
-----------------------------------------------
Legend:
::
∧ intersection
union
∘ concatenation (see below)
¬ complement
ϕ empty set (aka ∅)
λ singleton set containing just the empty string
I set of all letters in alphabet
∧ 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:
@ -71,7 +71,7 @@ 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
--------------
@ -94,11 +94,11 @@ The empty set and the set of just the empty string.
Two-letter Alphabet
~~~~~~~~~~~~~~~~~~~
I'm only going to use two symbols (at first) becaase this is enough to
Im only going to use two symbols (at first) becaase this is enough to
illustrate the algorithm and because you can represent any other
alphabet with two symbols (if you had to.)
I chose the names ``O`` and ``l`` (uppercase "o" and lowercase "L") to
I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
look like ``0`` and ``1`` (zero and one) respectively.
.. code:: ipython2
@ -108,18 +108,18 @@ look like ``0`` and ``1`` (zero and one) respectively.
Representing Regular Expressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To represent REs in Python I'm going to use tagged tuples. A *regular
To represent REs in Python Im going to use tagged tuples. A *regular
expression* is one of:
::
O
l
(KSTAR, R)
(NOT, R)
(AND, R, S)
(CONS, R, S)
(OR, R, S)
O
l
(KSTAR, R)
(NOT, R)
(AND, R, S)
(CONS, R, S)
(OR, R, S)
Where ``R`` and ``S`` stand for *regular expressions*.
@ -169,11 +169,11 @@ String Representation of RE Datastructures
``I``
~~~~~
Match anything. Often spelled "."
Match anything. Often spelled “.”
::
I = (0|1)*
I = (0|1)*
.. code:: ipython2
@ -196,8 +196,8 @@ The example expression from Brzozowski:
::
(.111.) & (.01 + 11*)'
a & (b + c)'
(.111.) & (.01 + 11*)'
a & (b + c)'
Note that it contains one of everything.
@ -221,7 +221,7 @@ Note that it contains one of everything.
``nully()``
~~~~~~~~~~~
Let's get that auxiliary predicate function ``δ`` out of the way.
Lets get that auxiliary predicate function ``δ`` out of the way.
.. code:: ipython2
@ -256,10 +256,10 @@ Let's get that auxiliary predicate function ``δ`` out of the way.
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.
@ -359,7 +359,7 @@ are *pure* so this is fine.
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
@ -409,8 +409,8 @@ expressions from growing too large.
return derv
Let's try it out...
-------------------
Lets try it out…
-----------------
(FIXME: redo.)
@ -460,27 +460,27 @@ Should match:
::
(.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 youll see that we never use the “set-ness” of the symbols ``O``
and ``l``. The only time Python set operators (``&`` and ``|``) appear
is in the ``nully()`` function, and there they operate on (recursively
computed) outputs of that function, never ``O`` and ``l``.
@ -489,33 +489,33 @@ What if we try:
::
(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
@ -529,9 +529,9 @@ machine transition table.
::
.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 1s and not ending in 01 nor composed of all 1s.”
.. figure:: attachment:omg.svg
:alt: omg.svg
@ -540,32 +540,32 @@ Says, "Three or more 1's and not ending in 01 nor composed of all 1's."
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/>`__.) Youll see that only
paths that lead to one of the accepting states will match the regular
expression. All other paths will terminate at one of the non-accepting
states.
There's a happy path to ``g`` along 111:
Theres 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`` youre stuck there eating 1s until you see a 0,
which takes you to the ``i→j→i|i→j→h→i`` “trap”. You cant reach any
other states from those two loops.
If you see a 0 before you see 111 you will reach ``b``, which forms
another "trap" with ``d`` and ``f``. The only way out is another happy
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 1s or as many 0 in a
row and still be either still at ``h`` (for 1s) or move to ``i`` (for
0s). If you find yourself at ``i`` you can see as many 0s, or
repetitions of 10, as there are, but if you see just a 1 you move to
``j``.
@ -575,14 +575,14 @@ RE to FSM
So how do we get the state machine from the regular expression?
It turns out that each RE is effectively a state, and each arrow points
to the derivative RE in respect to the arrow's symbol.
to the derivative RE in respect to the arrows symbol.
If we label the initial RE ``a``, we can say:
::
a --0--> ∂0(a)
a --1--> ∂1(a)
a --0--> ∂0(a)
a --1--> ∂1(a)
And so on, each new unique RE is a new state in the FSM table.
@ -590,18 +590,18 @@ Here are the derived REs at each state:
::
a = (.111.) & ((.01 | 11*)')
b = (.111.) & ((.01 | 1)')
c = (.111. | 11.) & ((.01 | 1*)')
d = (.111. | 11.) & ((.01 | ^)')
e = (.111. | 11. | 1.) & ((.01 | 1*)')
f = (.111. | 11. | 1.) & ((.01)')
g = (.01 | 1*)'
h = (.01)'
i = (.01 | 1)'
j = (.01 | ^)'
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"
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.
@ -764,16 +764,16 @@ Drive a FSM
There are *lots* of FSM libraries already. Once you have the state
transition table they should all be straightforward to use. State
Machine code is very simple. Just for fun, here is an implementation in
Python that imitates what "compiled" FSM code might look like in an
"unrolled" form. Most FSM code uses a little driver loop and a table
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
@ -790,8 +790,8 @@ function.
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
@ -831,7 +831,7 @@ labels.)
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`` isnt.
.. code:: ipython2
@ -885,7 +885,7 @@ Reversing the Derivatives to Generate Matching Strings
------------------------------------------------------
(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
@ -893,54 +893,54 @@ derivative-with-respect-to-N of some other state/RE:
::
c = d1(a)
b = d0(a)
b = d0(c)
...
i = d0(j)
j = d1(i)
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)*

View File

@ -11,51 +11,51 @@ Consider the ``x`` combinator:
::
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:
Lets try it:
.. code:: ipython2
@ -128,32 +128,32 @@ our quoted program:
::
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:
Lets try it out:
.. code:: ipython2
@ -208,20 +208,20 @@ Generating Multiples of Three and Five
--------------------------------------
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 youll 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.
@ -250,7 +250,7 @@ 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
@ -262,8 +262,7 @@ If we plug ``14811`` and ``[PE1.1]`` into our generator form...
[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
@ -306,15 +305,15 @@ if so.
(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
thats a little beyond the scope of this article. This solution does
extra work, but not much, and were not using it “in production” as they
say.)
Run 466 times
~~~~~~~~~~~~~
In the PE1 problem we are asked to sum all the multiples of three and
five less than 1000. It's worked out that we need to use all seven
five less than 1000. Its worked out that we need to use all seven
numbers sixty-six times and then four more.
.. code:: ipython2
@ -375,76 +374,76 @@ Consider:
::
[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``:
Lets 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
@ -467,8 +466,8 @@ Putting it all together:
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
@ -479,13 +478,13 @@ 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 its straightforward to define ``PE2`` as a recursive function that
generates terms in the Fibonacci sequence until they exceed four million
and sums the even ones.
@ -503,18 +502,18 @@ and sums the even ones.
4613732
Here's the collected program definitions:
Heres 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
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -523,16 +522,16 @@ Using ``o`` for odd and ``e`` for even:
::
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.

View File

@ -1,5 +1,5 @@
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>`__
====================================================================================
@ -13,8 +13,8 @@ means of:
- 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.
@ -37,7 +37,7 @@ 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 lets 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()``
@ -110,7 +110,7 @@ As a hylomorphism
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
~~~~~~~~~~~~
@ -127,7 +127,7 @@ hylomorphism combinator ``H`` from constituent parts.
::
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
@ -136,37 +136,37 @@ with the base case value ``c``.)
::
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``
------------------------------
@ -176,10 +176,10 @@ arguments out of the pieces given to the ``hylomorphism`` combinator.
::
H == [P] [pop c] [G] [dip F] genrec
[P] [c] [pop] swoncat [G] [F] [dip] swoncat genrec
[P] c unit [pop] swoncat [G] [F] [dip] swoncat genrec
[P] c [G] [F] [unit [pop] swoncat] dipd [dip] swoncat genrec
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
@ -190,7 +190,7 @@ 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
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
@ -198,7 +198,7 @@ expected order.
::
[P] c [G] [F] hylomorphism == H
[P] c [G] [F] hylomorphism == H
.. code:: ipython2
@ -369,39 +369,39 @@ An anamorphism can be defined as a hylomorphism that uses ``[]`` for
::
[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
@ -411,20 +411,20 @@ Untangle ``[G]`` from ``[pop []]`` using ``swap``.
::
[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
============
@ -434,48 +434,48 @@ A catamorphism can be defined as a hylomorphism that uses
::
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 doesnt 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 isnt 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
Im 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
@ -483,95 +483,95 @@ cata:
::
[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 isnt the one described in “Bananas…”. Thats 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
========================================
@ -582,26 +582,26 @@ An anamorphism followed by (composed with) a catamorphism is a
hylomorphism, with the advantage that the hylomorphism does not create
the intermediate list structure. The values are stored in either the
call stack, for those implementations that use one, or in the pending
expression ("continuation") for the Joypy interpreter. They still have
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
@ -1394,9 +1394,9 @@ A paramorphism ``P :: B -> A`` is a recursion combinator that uses
::
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.
@ -1405,10 +1405,10 @@ For Factorial function (types ``A`` and ``B`` are both integer):
::
n == 1
F == *
G == --
P == 1 <=
n == 1
F == *
G == --
P == 1 <=
.. code:: ipython2
@ -1418,23 +1418,23 @@ Try it with input 3 (omitting evaluation of predicate):
::
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
@ -1451,15 +1451,15 @@ Derive ``paramorphism`` from the form above.
::
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
@ -1479,24 +1479,24 @@ Derive ``paramorphism`` from the form above.
``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
@ -1539,22 +1539,22 @@ Right before the recursion begins we have:
::
[] [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
Theres 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
@ -1564,7 +1564,7 @@ and ``[G]`` for common prefix and extracted it.
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
@ -1575,22 +1575,22 @@ Hylo-, Ana-, Cata-
::
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
====================
@ -1598,54 +1598,54 @@ 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.
generators 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
~
@ -1658,21 +1658,21 @@ reverse order.
::
H == c swap [P] [pop] [G [F] dip] primrec
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
... 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
The end line here is the same as for above, but only because we didnt
evaluate ``F`` when it normally would have been.
3
@ -1684,22 +1684,22 @@ one item instead of two (the b is instead the duplicate of a.)
::
H == [P] [pop c] [[G] dupdip] [dip F] genrec
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
... 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
~
@ -1709,21 +1709,21 @@ and the combiner needs to work on the current item, this is the form:
::
W == c swap [P] [pop] [[F] dupdip G] primrec
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
... 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.
@ -1761,7 +1761,7 @@ catamorphic forms.
::
H == [P ] [pop c ] [G ] [dip F ] genrec
H == [P ] [pop c ] [G ] [dip F ] genrec
.. code:: ipython2
@ -2092,15 +2092,15 @@ 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.
"Too much is always better than not enough."
“Too much is always better than not enough.”

View File

@ -1,10 +1,10 @@
`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
`Newtons method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
=====================================================================
Let's use the Newton-Raphson method for finding the root of an equation
Lets use the Newton-Raphson method for finding the root of an equation
to write a function that can compute the square root of a number.
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
@ -20,9 +20,9 @@ computes the next approximation:
::
a F
---------
a'
a F
---------
a'
A Function to Compute the Next Approximation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -34,17 +34,17 @@ square root:
::
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
~~~~~~~~~~~~~~~~~~~~~~~~
@ -53,27 +53,27 @@ Our generator would be created by:
::
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 were writing. If we let 1 be the initial approximation:
::
1 n 1 / + 2 /
1 n/1 + 2 /
1 n + 2 /
n+1 2 /
(n+1)/2
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
@ -89,8 +89,8 @@ The generator can be written as:
[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...
Lets drive the generator a few time (with the ``x`` combinator) and
square the approximation to see how well it works
.. code:: ipython2
@ -105,42 +105,42 @@ square the approximation to see how well it works...
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
@ -151,10 +151,10 @@ Base-Case
::
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
@ -165,7 +165,7 @@ Recur
::
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``.
@ -175,14 +175,14 @@ Pretty straightforward:
::
a [b G] ε R0 [within] R1
a [b G] ε [popd x] dip [within] i
a [b G] popd x ε [within] i
[b G] x ε [within] i
b [c G] ε [within] i
b [c G] ε within
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
@ -196,15 +196,15 @@ The recursive function we have defined so far needs a slight preamble:
::
[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

File diff suppressed because it is too large Load Diff

View File

@ -10,9 +10,9 @@ Cf.
::
-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}`
@ -28,21 +28,21 @@ a definition without them.
::
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 * /
``±``
~~~~~
@ -52,14 +52,14 @@ replaces them with their sum and difference.
::
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``.
@ -72,20 +72,20 @@ the variables:
::
b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
b [neg] dupdip sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
b a c [[neg] dupdip sqr 4] dipd * * - sqrt pm a 2 * [/] cons app2
b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
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 its 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:
Lets try it out:
.. code:: ipython2

View File

@ -10,44 +10,43 @@ several generic specializations.
::
[if] [then] [rec1] [rec2] genrec
---------------------------------------------------------------------
[if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
[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:
From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun:
"The genrec combinator takes four program parameters in addition to
whatever data parameters it needs. Fourth from the top is an
if-part, followed by a then-part. If the if-part yields true, then
the then-part is executed and the combinator terminates. The other
two parameters are the rec1-part and the rec2-part. If the if-part
yields false, the rec1-part is executed. Following that the four
program parameters and the combinator are again pushed onto the
stack bundled up in a quoted form. Then the rec2-part is executed,
where it will find the bundled form. Typically it will then execute
the bundled form, either with i or with app2, or some other
combinator."
“The 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.
@ -59,9 +58,9 @@ Primitive recursive functions are those where ``R2 == i``.
::
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>`__
------------------------------------------------------------------------------------
@ -75,8 +74,8 @@ is a recursive function ``H :: A -> C`` that converts a value of type
- 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.
@ -96,12 +95,12 @@ 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
-------------------
@ -111,7 +110,7 @@ hylomorphism combinator ``H`` from constituent parts.
::
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
@ -120,37 +119,37 @@ with the base case value ``c``.)
::
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
-----------------------------------------
@ -160,9 +159,9 @@ arguments out of the pieces given to the ``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:
@ -174,17 +173,17 @@ So:
::
H == [P] [pop c] [G] [dip F] genrec
[P] [c] [pop] swoncat [G] [F] [dip] swoncat genrec
[P] c unit [pop] swoncat [G] [F] [dip] swoncat genrec
[P] c [G] [F] [unit [pop] swoncat] dipd [dip] swoncat genrec
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
@ -193,7 +192,7 @@ the left so we have a definition for ``hylomorphism``:
Example: Finding `Triangular Numbers <https://en.wikipedia.org/wiki/Triangular_number>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let's write a function that, given a positive integer, returns the sum
Lets write a function that, given a positive integer, returns the sum
of all positive integers less than that one. (In this case the types
``A``, ``B`` and ``C`` are all ``int``.)
@ -208,7 +207,7 @@ To sum a range of integers from 0 to *n* - 1:
define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')
Let's try it:
Lets try it:
.. code:: ipython2
@ -236,30 +235,30 @@ Four Specializations
There are at least four kinds of recursive combinator, depending on two
choices. The first choice is whether the combiner function ``F`` should
be evaluated during the recursion or pushed into the pending expression
to be "collapsed" at the end. The second choice is whether the combiner
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
generators output, in other words, whether ``F`` or ``G`` should run
first in the recursive branch.
::
H1 == [P] [pop c] [G ] [dip F] genrec
H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
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.
@ -269,31 +268,31 @@ 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``
@ -307,53 +306,53 @@ reverse order.
::
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 youll see that the combiner ``F`` only
gets to operate on the results of ``G``, it never “sees” the first value
``a``. If the combiner and the generator both need to work on the
current value then ``dup`` must be used, and the generator must produce
one item instead of two (the b is instead the duplicate of a.)
::
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
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``
~~~~~~
@ -364,22 +363,22 @@ the form:
::
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
-----------
@ -390,13 +389,10 @@ values.
::
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.
@ -406,8 +402,8 @@ Each of the above variations can be used to make four slightly different
::
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
@ -428,8 +424,8 @@ Each of the above variations can be used to make four slightly different
::
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
@ -450,8 +446,8 @@ Each of the above variations can be used to make four slightly different
::
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
@ -472,8 +468,8 @@ Each of the above variations can be used to make four slightly different
::
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
@ -503,7 +499,7 @@ and makes some new value.
::
C == [not] c [uncons swap] [F] hylomorphism
C == [not] c [uncons swap] [F] hylomorphism
.. code:: ipython2
@ -513,7 +509,7 @@ An example of a catamorphism is the sum function.
::
sum == [not] 0 [swuncons] [+] hylomorphism
sum == [not] 0 [swuncons] [+] hylomorphism
.. code:: ipython2
@ -585,16 +581,16 @@ For the Factorial function:
::
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
@ -613,31 +609,31 @@ With:
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
@ -656,39 +652,39 @@ We would use:
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.”

View File

@ -4,8 +4,8 @@ Replacing Functions in the Dictionary
For now, there is no way to define new functions from within the Joy
language. All functions (and the interpreter) all accept and return a
dictionary parameter (in addition to the stack and expression) so that
we can implement e.g. a function that adds new functions to the
dictionary. However, 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, theres no function that does that. Adding a new
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.
@ -74,8 +74,8 @@ Both ``sum`` and ``size`` each convert a sequence to a single value.
::
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

View File

@ -17,10 +17,10 @@ symbols together, juxtaposition:
::
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
------
@ -29,72 +29,72 @@ Do one thing or another.
::
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 doesnt *have*
to be Boolean because Pythons rules for “truthiness” will be used to
evaluate it. I reflect this in the structure of the stack effect comment
of ``branch``, it will only accept Boolean values, and in the definition
of ``ifte`` above by including ``not`` in the quote, which also has the
@ -107,17 +107,17 @@ Do one thing zero or more times.
::
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
@ -128,21 +128,21 @@ constructs that do not need to be directly self-referential, unlike
::
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
@ -150,15 +150,15 @@ boolean flag for the next iteration:
::
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``
~~~~~~~~~
@ -170,21 +170,21 @@ flag for the next iteration:
::
[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
--------
@ -192,11 +192,11 @@ 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 couldnt be
reimplemented in terms of e.g. Python threads. I am not concerned with
performance of the system just yet, only the elegance of the code it
allows us to write.
@ -207,27 +207,27 @@ Joy has a few parallel combinators, the main one being ``cleave``:
::
... x [A] [B] cleave
---------------------------------------------------------
... [x ...] [A] infra first [x ...] [B] infra first
---------------------------------------------------------
... a b
... 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.)
Elliotts “Compiling to Categories” paper, et. al.)
Just a thought, if you ``cleave`` two jobs and one requires more time to
finish than the other you'd like to be able to assign resources
finish than the other youd 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
@ -235,35 +235,35 @@ than one value:
::
... 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
(Im not sure why ``cleave`` was specified to take that value, I may
make a combinator that does the same thing but without expecting a
value.)
::
clv == [i] app2
clv == [i] app2
[A] [B] clv
------------------
a b
[A] [B] clv
------------------
a b
``map``
~~~~~~~
@ -273,10 +273,10 @@ The common ``map`` function in Joy should also be though of as a
::
[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`` couldnt distribute
the ``Q`` function over e.g. a pool of worker CPUs.
``pam``
~~~~~~~
@ -285,16 +285,16 @@ One of my favorite combinators, the ``pam`` combinator is just:
::
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -302,7 +302,7 @@ 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
^^^^^^^^^^^^^^^
@ -313,24 +313,24 @@ stack could be replaced by its output stack.
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 Im not going to worry about
it. (And I think the Categories can deal with it anyhow? Incremental
evaluation, yeah?)

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
Treating Trees II: ``treestep``
===============================
Let's consider a tree structure, similar to one described `"Why
functional programming matters" by John
Lets consider a tree structure, similar to one described `“Why
functional programming matters by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__,
that consists of a node value followed by zero or more child trees. (The
asterisk is meant to indicate the `Kleene
@ -10,7 +10,7 @@ star <https://en.wikipedia.org/wiki/Kleene_star>`__.)
::
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
@ -18,15 +18,15 @@ base-case function ``[B]``, and two quoted programs ``[N]`` and ``[C]``.
::
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
@ -34,11 +34,11 @@ combine the result with ``C``.
::
[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 well experiment with making ``map`` part of ``C`` so you can
use other combinators.)
Derive the recursive function.
@ -49,59 +49,59 @@ will produce.
::
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``.
Lets 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.
-----------------------------------------------
@ -110,26 +110,26 @@ Working backwards:
::
[not] [B] [uncons [N] dip] [map C] genrec
[B] [not] swap [uncons [N] dip] [map C] genrec
[B] [uncons [N] dip] [[not] swap] dip [map C] genrec
^^^^^^^^^^^^^^^^
[B] [[N] dip] [uncons] swoncat [[not] swap] dip [map C] genrec
[B] [N] [dip] cons [uncons] swoncat [[not] swap] dip [map C] genrec
^^^^^^^^^^^^^^^^^^^^^^^^^^^
[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.
@ -140,10 +140,10 @@ Working backwards:
::
[not] [B] [uncons [N] dip] [map C] genrec
[not] [B] [N] [dip] cons [uncons] swoncat [map C] genrec
[B] [N] [not] roll> [dip] cons [uncons] swoncat [map C] genrec
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[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``
-------------------
@ -171,7 +171,7 @@ all nodes in a tree with this function:
::
sumtree == [pop 0] [] [sum +] treestep
sumtree == [pop 0] [] [sum +] treestep
.. code:: ipython2
@ -181,9 +181,9 @@ Running this function on an empty tree value gives zero:
::
[] [pop 0] [] [sum +] treestep
------------------------------------
0
[] [pop 0] [] [sum +] treestep
------------------------------------
0
.. code:: ipython2
@ -199,11 +199,11 @@ Running it on a non-empty node:
::
[n tree*] [pop 0] [] [sum +] treestep
n [tree*] [[pop 0] [] [sum +] treestep] map sum +
n [ ... ] sum +
n m +
n+m
[n tree*] [pop 0] [] [sum +] treestep
n [tree*] [[pop 0] [] [sum +] treestep] map sum +
n [ ... ] sum +
n m +
n+m
.. code:: ipython2
@ -310,7 +310,7 @@ Redefining the Ordered Binary Tree in terms of ``treestep``.
::
Tree = [] | [[key value] left right]
Tree = [] | [[key value] left right]
What kind of functions can we write for this with our ``treestep``?
@ -318,26 +318,26 @@ 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
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 doesnt quite work:
.. code:: ipython2
@ -349,25 +349,25 @@ This doesn't quite work:
3 'B' 'B'
Doesn't work because ``map`` extracts the ``first`` item of whatever its
Doesnt work because ``map`` extracts the ``first`` item of whatever its
mapped function produces. We have to return a list, rather than
depositing our results directly on the stack.
::
[key value] N [left right] [K] map C
[key value] 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
@ -388,18 +388,18 @@ From here:
::
key [[lk] [rk]] C
key [[lk] [rk]] i
key [lk] [rk] roll<
[lk] [rk] key swons concat
[lk] [key rk] concat
[lk key rk]
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
@ -414,20 +414,20 @@ So:
With ``treegrind``?
-------------------
The ``treegrind`` function doesn't include the ``map`` combinator, so
The ``treegrind`` function doesnt include the ``map`` combinator, so
the ``[C]`` function must arrange to use some combinator on the quoted
recursive copy ``[K]``. With this function, the pattern for processing a
non-empty node is:
::
node N [tree*] [K] C
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
@ -454,7 +454,7 @@ Iteration through the nodes
[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
@ -485,28 +485,28 @@ I think we do:
::
[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
Well start by saying that the base-case (the key is not in the tree) is
user defined, and the per-node function is just the query key literal:
::
[B] [query_key] [C] treegrind
[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``:
Lets 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``
~~~~~~~~~~~~~~~~~~~
@ -516,16 +516,16 @@ equal):
::
[key value] query_key [left right] [K] P
[key value] query_key [left right] [K] roll<
[key value] [left right] [K] query_key [roll< uncons swap] dip
[key value] 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>``.)
@ -533,15 +533,15 @@ So now:
::
[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``
~~~~~
@ -550,27 +550,27 @@ Easy.
::
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.

View File

@ -98,7 +98,7 @@ An Example
(... [3 4 ] 2 1 0 -- ... [1 2 ])
Unification Works "in Reverse"
Unification Works “in Reverse”
------------------------------
.. code:: ipython2

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
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
@ -17,10 +17,9 @@ it, and rebuild it using the "zipper" technique.
Trees
-----
In Joypy there aren't any complex datastructures, just ints, floats,
In Joypy there arent any complex datastructures, just ints, floats,
strings, Symbols (strings that are names of functions) and sequences
(aka lists, aka quoted literals, aka aggregates, etc...), but we can
build
(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.
@ -45,12 +44,12 @@ In Joy we can do this with the following words:
::
z-down == [] swap uncons swap
z-up == swons swap shunt
z-right == [swons] cons dip uncons swap
z-left == swons [uncons swap] dip swap
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
Lets use them to change 25 into 625. The first time a word is used I
show the trace so you can see how it works. If we were going to use
these a lot it would make sense to write Python versions for efficiency,
but see below.
@ -208,8 +207,8 @@ 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
@ -247,8 +246,8 @@ or "address" any particular item in a Joy tree structure.
[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 youll see that about half of it is the
``dip`` and ``infra`` combinators de-quoting programs and “digging” into
the subject datastructure. Instead of maintaining temporary results on
the stack they are pushed into the pending expression (continuation).
When ``sqr`` has run the rest of the pending expression rebuilds the
@ -264,12 +263,12 @@ been embedded in a nested series of quoted programs, e.g.:
::
[...] [Q] [dip dip infra dip infra dip infra] Z
-------------------------------------------------------------
[...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
[...] [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 isnt hard to make.
.. code:: ipython2
@ -333,21 +332,21 @@ a string made from only two characters.
::
[...] [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"
Its easy to read off (in reverse) the right sequence of “d” and “i”
from the subject datastructure:
::
[ n [ n [ n n x ...
i d i d i d d Bingo!
[ n [ n [ n n x ...
i d i d i d d Bingo!

View File

@ -2,7 +2,7 @@
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
@ -13,25 +13,27 @@ here <https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.694.2614>`__
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
--------------------------------
@ -50,48 +52,48 @@ 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″
Initial Definition
~~~~~~~~~~~~~~~~~~
We're building a list of values so this is an "anamorphism". (An
Were 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`` doesnt 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``
~~~~~~~~~~~~~
@ -101,11 +103,11 @@ 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 ````
~~~~~~~~~~~~~~~~~~~
@ -115,10 +117,10 @@ in the list.
::
[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``
~~~~~~~~~~~~~~~
@ -128,14 +130,14 @@ less that two items in them:
::
P == size 1 <=
P == size 1 <=
Let's see what we've got so far:
Lets see what weve 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
~~~~~~~~~~~~~~~~~~~~~~
@ -152,7 +154,7 @@ This works to a point, but it throws away the last term:
[1 3]
Hmm... Let's take out the ``pop`` for a sec...
Hmm… Lets take out the ``pop`` for a sec…
.. code:: ipython2
@ -165,9 +167,9 @@ Hmm... Let's take out the ``pop`` for a sec...
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
@ -186,22 +188,22 @@ So we have:
::
[⨁] 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
@ -240,22 +242,22 @@ And so:
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
@ -267,41 +269,41 @@ Problem 2.
'hello\nworld'
Again ignoring the actual task let's just derive ``Lines``:
Again ignoring the actual task lets 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?
------------------
@ -311,27 +313,27 @@ properties are discussed. Am I 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 dont 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.

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -27,12 +28,10 @@
<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>
@ -40,38 +39,13 @@
<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>
@ -79,23 +53,17 @@
</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>
@ -106,7 +74,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -27,8 +28,6 @@
<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>
@ -57,11 +56,11 @@
<span class="sd">match the behaviour of the original version(s) written in C.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="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>
@ -146,34 +145,10 @@
</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>
@ -183,23 +158,17 @@
</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>
@ -210,7 +179,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -27,8 +28,6 @@
<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>
@ -57,29 +56,29 @@
<span class="sd">returns a dictionary of Joy functions suitable for use with the joy()</span>
<span class="sd">function.</span>
<span class="sd">&#39;&#39;&#39;</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">&#39;Loading library.&#39;</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">&lt;</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>
@ -136,6 +135,7 @@
<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"># &quot;sec&quot;: 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>
@ -147,6 +147,7 @@
<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&#39;re building.</span>
<span class="n">_dictionary</span> <span class="o">=</span> <span class="p">{}</span>
@ -256,43 +257,43 @@
<span class="n">definitions</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;&#39;&#39;</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 &gt;] [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 &gt;] 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 &lt;=] [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&gt; 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 &gt;] [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 &gt;] 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 &lt;=] [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&gt; 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">&#39;&#39;&#39;</span>
<span class="c1">#</span>
<span class="c1">#</span>
@ -389,14 +390,14 @@
<span class="sd"> Provide implementation of defined functions, and some helper methods.</span>
<span class="sd"> &#39;&#39;&#39;</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>
@ -408,10 +409,7 @@
<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"> &#39;&#39;&#39;</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">&#39;==&#39;</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">&#39;Definition </span><span class="si">%r</span><span class="s1"> failed&#39;</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>
@ -440,7 +438,11 @@
<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">&#39;==&#39;</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">&#39;#&#39;</span><span class="p">)</span>
<span class="p">)</span>
<span class="c1">#</span>
@ -948,16 +950,17 @@
<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">&#39;choice&#39;</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">&#39;first&#39;</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">&#39;getitem&#39;</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">&#39;genrec&#39;</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">&#39;loop&#39;</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">&#39;getitem&#39;</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">&#39;i&#39;</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">&#39;ifte&#39;</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">&#39;infra&#39;</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">&#39;loop&#39;</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">&#39;pop&#39;</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">&#39;primrec&#39;</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">&#39;step&#39;</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">&#39;times&#39;</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">&#39;swaack&#39;</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">&#39;times&#39;</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>
@ -1059,9 +1062,9 @@
<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 &quot;Recursion Theory and Joy&quot; (j05cmp.html) by Manfred von Thun:</span>
<span class="sd"> &quot;The genrec combinator takes four program parameters in addition to</span>
@ -1096,14 +1099,14 @@
<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"> &#39;&#39;&#39;</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>
@ -1138,6 +1141,49 @@
<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">&#39;&#39;&#39;</span>
<span class="sd"> From the &quot;Overview of the language JOY&quot;:</span>
<span class="sd"> &gt; 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"> &gt; 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 &gt; 0</span>
<span class="sd"> n (n-1) [Base] [Recur] primrec Recur</span>
<span class="sd"> &#39;&#39;&#39;</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">&lt;=</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"># &#39;&#39;&#39;</span>
<span class="c1"># The cleave combinator expects two quotations, and below that an item X.</span>
@ -1671,34 +1717,10 @@
</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>
@ -1708,23 +1730,17 @@
</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>
@ -1735,7 +1751,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -27,8 +28,6 @@
<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>
@ -70,12 +69,12 @@
<span class="sd">around square brackets.</span>
<span class="sd">&#39;&#39;&#39;</span>
<span class="kn">from</span> <span class="nn">re</span> <span class="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">&#39;-?\d+\.\d*&#39;</span>
<span class="n">FLOAT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;-?\d+\.\d*(e(-|\+)\d+)+&#39;</span>
<span class="n">INT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;-?\d+&#39;</span>
<span class="n">SYMBOL</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;[•\w!@$%^&amp;*()_+&lt;&gt;?|\/;:`~,.=-]+&#39;</span>
<span class="n">BRACKETS</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;\[|\]&#39;</span>
@ -159,34 +158,10 @@
</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>
@ -196,23 +171,17 @@
</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>
@ -223,7 +192,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -27,8 +28,6 @@
<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>
@ -73,12 +72,12 @@
<span class="sd">&#39;&#39;&#39;</span>
<span class="c1"># (Kinda clunky and hacky. This should be swapped out in favor of much</span>
<span class="c1"># smarter stuff.)</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="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>
@ -115,7 +114,7 @@
<span class="sd"> trace.</span>
<span class="sd"> &#39;&#39;&#39;</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>
@ -128,7 +127,7 @@
<span class="sd"> &#39;&#39;&#39;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">))</span></div>
<span class="k">def</span> <span class="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">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">go</span><span class="p">())</span>
<div class="viewcode-block" id="TracePrinter.go"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.TracePrinter.go">[docs]</a> <span class="k">def</span> <span class="nf">go</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
@ -163,34 +162,10 @@
</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>
@ -200,23 +175,17 @@
</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>
@ -227,7 +196,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -27,8 +28,6 @@
<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>
@ -59,8 +58,8 @@
<span class="sd">There is no &quot;Stack&quot; 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>
@ -106,7 +105,7 @@
<span class="sd">&#39;&#39;&#39;</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">&#39;&#39;&#39;Convert a Python list (or other sequence) to a Joy stack::</span>
@ -232,34 +231,10 @@
</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>
@ -269,23 +244,17 @@
</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>
@ -296,7 +265,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -3,7 +3,7 @@
/* -- 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;
@ -107,7 +107,7 @@ div.sphinxsidebarwrapper p.blurb {
div.sphinxsidebar h3,
div.sphinxsidebar h4 {
font-family: Georgia, serif;
font-family: 'Garamond', 'Georgia', serif;
color: #444;
font-size: 24px;
font-weight: normal;
@ -151,7 +151,7 @@ div.sphinxsidebar ul li.toctree-l2 > a {
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;
}
@ -166,19 +166,6 @@ div.sphinxsidebar hr {
width: 50%;
}
div.sphinxsidebar .badge {
border-bottom: none;
}
div.sphinxsidebar .badge:hover {
border-bottom: none;
}
/* To address an issue with donation coming after search */
div.sphinxsidebar h3.donation {
margin-top: 10px;
}
/* -- body styles ----------------------------------------------------------- */
a {
@ -197,7 +184,7 @@ div.body h3,
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;
@ -238,7 +225,7 @@ div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
}
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;
@ -327,7 +314,7 @@ p.admonition-title:after {
}
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;
}
@ -651,51 +638,4 @@ table.docutils.citation, table.docutils.citation td, table.docutils.citation th
-moz-box-shadow: none;
-webkit-box-shadow: none;
box-shadow: none;
}
/* relbar */
.related {
line-height: 30px;
width: 100%;
font-size: 0.9rem;
}
.related.top {
border-bottom: 1px solid #EEE;
margin-bottom: 20px;
}
.related.bottom {
border-top: 1px solid #EEE;
}
.related ul {
padding: 0;
margin: 0;
list-style: none;
}
.related li {
display: inline;
}
nav#rellinks {
float: right;
}
nav#rellinks li+li:before {
content: "|";
}
nav#breadcrumbs li+li:before {
content: "\00BB";
}
/* Hide certain items when printing */
@media print {
div.related {
display: none;
}
}

View File

@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@ -81,10 +81,6 @@ div.sphinxsidebar input {
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
@ -231,16 +227,6 @@ a.headerlink {
visibility: hidden;
}
a.brackets:before,
span.brackets > a:before{
content: "[";
}
a.brackets:after,
span.brackets > a:after {
content: "]";
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
@ -289,12 +275,6 @@ img.align-center, .figure.align-center, object.align-center {
margin-right: auto;
}
img.align-default, .figure.align-default {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
@ -303,10 +283,6 @@ img.align-default, .figure.align-default {
text-align: center;
}
.align-default {
text-align: center;
}
.align-right {
text-align: right;
}
@ -378,11 +354,6 @@ table.align-center {
margin-right: auto;
}
table.align-default {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
@ -416,16 +387,6 @@ table.citation td {
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 {
@ -466,13 +427,6 @@ table.field-list td, table.field-list th {
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist td {
vertical-align: top;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
@ -495,58 +449,11 @@ ol.upperroman {
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;
}
@ -619,12 +526,6 @@ dl.glossary dt {
font-style: oblique;
}
.classifier:before {
font-style: normal;
margin: 0.5em;
content: ":";
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
@ -672,10 +573,6 @@ div.code-block-caption + div > div.highlight > pre {
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;

View File

@ -4,7 +4,7 @@
*
* 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.
*
*/
@ -87,13 +87,14 @@ jQuery.fn.highlightText = function(text, className) {
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var bbox = span.getBBox();
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
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});
@ -149,9 +150,7 @@ var Documentation = {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
this.initOnKeyListeners();
}
},
/**
@ -283,11 +282,10 @@ var Documentation = {
},
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');
@ -312,4 +310,4 @@ _ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});
});

View File

@ -1,12 +1,9 @@
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'
};

File diff suppressed because one or more lines are too long

View File

@ -1,54 +1,331 @@
/*
* 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,
/* Non-minified version JS is _stemmer.js if file is provided */
/**
* Porter Stemmer
*/
var Stemmer = function() {
// query found in title
title: 15,
partialTitle: 7,
// query found in terms
term: 5,
partialTerm: 2
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
*/
@ -58,19 +335,6 @@ var Search = {
_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) {
@ -135,7 +399,7 @@ var Search = {
this.out = $('#search-results');
this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out);
this.dots = $('<span></span>').appendTo(this.title);
this.status = $('<p class="search-summary">&nbsp;</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...'));
@ -153,6 +417,7 @@ var Search = {
*/
query : function(query) {
var i;
var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"];
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
@ -250,9 +515,7 @@ var Search = {
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\/$/)) {
@ -260,17 +523,15 @@ var Search = {
} 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);
@ -278,7 +539,11 @@ var Search = {
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;
@ -328,13 +593,12 @@ var Search = {
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) {
@ -401,19 +665,6 @@ var Search = {
{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;})) {
@ -433,7 +684,7 @@ var Search = {
for (j = 0; j < _files.length; j++) {
file = _files[j];
if (!(file in scoreMap))
scoreMap[file] = {};
scoreMap[file] = {}
scoreMap[file][word] = o.score;
}
});
@ -441,7 +692,7 @@ var Search = {
// 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];
@ -453,12 +704,8 @@ var Search = {
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++) {
@ -489,8 +736,7 @@ var Search = {
* 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() {
@ -512,4 +758,4 @@ var Search = {
$(document).ready(function() {
Search.init();
});
});

View File

@ -1,19 +1,20 @@
<!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 &#8212; 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" />
@ -28,8 +29,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
@ -87,8 +86,6 @@
<li><a href="library.html#joy.library.DefinitionWrapper.add_definitions">add_definitions() (joy.library.DefinitionWrapper class method)</a>
</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>
@ -197,8 +194,6 @@
<li><a href="library.html#joy.utils.generated_library.first_two">first_two() (in module joy.utils.generated_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>
@ -257,8 +252,6 @@
<li><a href="library.html#joy.library.inscribe_">inscribe_() (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>
@ -270,57 +263,22 @@
<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>
@ -329,22 +287,8 @@
<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>
@ -371,29 +315,12 @@
</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>
@ -401,10 +328,6 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<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>
@ -432,10 +355,10 @@
</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>
@ -447,6 +370,8 @@
<li><a href="library.html#joy.utils.generated_library.popopdd">popopdd() (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>
@ -504,8 +429,6 @@
</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>
@ -537,8 +460,6 @@
<li><a href="parser.html#joy.parser.text_to_expression">text_to_expression() (in module joy.parser)</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>
@ -628,34 +549,10 @@
</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>
@ -663,23 +560,17 @@
</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>
@ -690,7 +581,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -28,8 +29,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="thun-release-documentation">
@ -44,10 +43,10 @@ between Thun and the originals, other than being written in Python, is
that it works by the “Continuation-Passing Style”.</p>
<p>Joy is:</p>
<ul class="simple">
<li><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
@ -69,10 +68,10 @@ itself.</p>
<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">
@ -161,41 +160,29 @@ interesting aspects. Its quite a treasure trove.</p>
<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>
@ -204,24 +191,25 @@ interesting aspects. Its quite a treasure trove.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/index.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -232,7 +220,7 @@ interesting aspects. Its quite a treasure trove.</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="joy-interpreter">
@ -40,9 +39,9 @@
<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.
@ -50,56 +49,68 @@ Literals are put onto the stack and functions are looked up in the
disctionary and executed.</p>
<p>The viewer is a function that is called with the stack and expression
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>
@ -107,36 +118,17 @@ on every iteration, its return value is ignored.</p>
</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>
@ -146,24 +138,25 @@ on every iteration, its return value is ignored.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/joy.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -174,7 +167,7 @@ on every iteration, its return value is ignored.</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="categorical-programming">
@ -40,58 +39,16 @@
<p>In Manfred von Thuns article <a class="reference external" href="http://www.kevinalbrecht.com/code/joy-mirror/j08cnt.html">Joy compared with other functional languages</a> he asks, “Could the language of categories be used for writing programs? Any lambda expression can be translated into a categorical expression, so the language of categories is expressively complete. But this does not make it a suitable language for writing programs. As it stands it is a very low-level language.”</p>
<p>In <a class="reference external" href="http://conal.net/papers/compiling-to-categories/">Compiling to categories</a> Conal Elliott give a taste of what this might mean.</p>
<blockquote>
<div><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 hes doing is translating lambda forms into a kind of “point-free” style that is very close to Joy code (although more verbose) and then showing how to instantiate that code over different categories to get several different kinds of program out of the same code.</p>
</div>
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
@ -102,24 +59,25 @@
</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>
@ -130,7 +88,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -28,14 +29,12 @@
<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>Brzozowskis 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>Brzozowskis 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
@ -96,14 +95,14 @@ R∘λ = λ∘R = R
</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">&#39;&#39;</span><span class="p">})</span> <span class="c1"># λ</span>
</pre></div>
</div>
@ -115,7 +114,7 @@ illustrate the algorithm and because you can represent any other
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">&#39;0&#39;</span><span class="p">}),</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">&#39;1&#39;</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">&#39;0&#39;</span><span class="p">}),</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">&#39;1&#39;</span><span class="p">})</span>
</pre></div>
</div>
</div>
@ -133,7 +132,7 @@ expression</em> is one of:</p>
</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">&#39;and cons * not or&#39;</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">&#39;and cons * not or&#39;</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
@ -141,7 +140,7 @@ only, these datastructures are immutable.</p>
</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">&#39;&#39;&#39;</span>
<span class="sd"> Return a nice string repr for a regular expression datastructure.</span>
<span class="sd"> &#39;&#39;&#39;</span>
@ -180,10 +179,10 @@ only, these datastructures are immutable.</p>
<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>
@ -198,13 +197,13 @@ only, these datastructures are immutable.</p>
</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">&amp;</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">&#39;)</span>
@ -214,7 +213,7 @@ only, these datastructures are immutable.</p>
<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>Lets 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">&#39;&#39;&#39;</span>
<span class="sd"> δ - Return λ if λ ⊆ R otherwise ϕ.</span>
<span class="sd"> &#39;&#39;&#39;</span>
@ -252,7 +251,7 @@ only, these datastructures are immutable.</p>
<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>
@ -296,7 +295,7 @@ derivation.</p>
</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>
@ -306,7 +305,7 @@ derivation.</p>
</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>
@ -325,14 +324,14 @@ derivation.</p>
<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>
@ -347,7 +346,7 @@ are <em>pure</em> so this is fine.</p>
<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>
@ -392,10 +391,10 @@ expressions from growing too large.</p>
</div>
</div>
</div>
<div class="section" id="let-s-try-it-out">
<h2>Lets 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>Lets 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">&#39;0&#39;</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">&#39;1&#39;</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">&#39;0&#39;</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">&#39;1&#39;</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>
@ -453,7 +452,7 @@ expressions from growing too large.</p>
</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.&nbsp;each byte
of the ASCII code. Or we can generalize this code. If you study the code
above youll see that we never use the “set-ness” of the symbols <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">&amp;</span></code> and <code class="docutils literal notranslate"><span class="pre">|</span></code>) appear
@ -499,8 +498,8 @@ machine transition table.</p>
</pre></div>
</div>
<p>Says, “Three or more 1s and not ending in 01 nor composed of all 1s.”</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
@ -553,18 +552,18 @@ a --1--&gt; ∂1(a)
<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">&amp;</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">&#39;0&#39;</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">&#39;1&#39;</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">&#39;0&#39;</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">&#39;1&#39;</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&#39;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>
@ -590,7 +589,7 @@ disappears once it has been matched.</p>
<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>
@ -616,7 +615,7 @@ disappears once it has been matched.</p>
<span class="p">(</span><span class="s1">&#39;j&#39;</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">&#39;h&#39;</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">&#39;h&#39;</span><span class="p">,</span> <span class="s1">&#39;i&#39;</span><span class="p">}</span>
@ -627,7 +626,7 @@ disappears once it has been matched.</p>
<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">&#39;&#39;&#39;</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">&#39;&#39;&#39;</span><span class="se">\</span>
<span class="s1">digraph finite_state_machine {</span>
<span class="s1"> rankdir=LR;</span>
<span class="s1"> size=&quot;8,5&quot;</span>
@ -651,7 +650,7 @@ generate the diagram above.</p>
<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>
@ -697,7 +696,7 @@ hard-code the information in the table into a little patch of branches.</p>
<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>
@ -712,7 +711,7 @@ function.</p>
<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>
@ -733,7 +732,7 @@ and “0” characters, not bits.)</p>
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>
@ -748,11 +747,11 @@ labels.)</p>
<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> isnt.</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">&#39;</span><span class="si">%05s</span><span class="s1">&#39;</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>
@ -822,7 +821,7 @@ derivative-with-respect-to-N of some other state/RE:</p>
<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></p>
<p></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>
@ -843,50 +842,46 @@ derivative-with-respect-to-N of some other state/RE:</p>
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2 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">Brzozowskis 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">&amp;</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">Lets 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>
@ -897,24 +892,25 @@ derivative-with-respect-to-N of some other state/RE:</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/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>
@ -925,7 +921,7 @@ derivative-with-respect-to-N of some other state/RE:</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="thun-joy-in-python">
@ -39,18 +38,18 @@
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 &quot;warranty&quot;.
This is free software, and you are welcome to redistribute it
under certain conditions; type &quot;sharing&quot; for details.
@ -58,7 +57,7 @@ Type &quot;words&quot; to see a list of all words, and &quot;[&lt;name&gt;] help
docs for a word.
&lt;-top
&lt;-top
joy? _
</pre></div>
@ -67,7 +66,14 @@ joy? _
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 &lt;-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 +
@ -150,19 +156,19 @@ like that.</p>
</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">&#39;1 2 3 4 5&#39;</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">&#39;1 2 3 4 5&#39;</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">&#39;[1 2 3] 4 5&#39;</span><span class="p">)</span> <span class="c1"># Three items, the first is a list with three items</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;[1 2 3] 4 5&#39;</span><span class="p">)</span> <span class="c1"># Three items, the first is a list with three items</span>
</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">&#39;1 23 [&quot;four&quot; [-5.0] cons] 8888&#39;</span><span class="p">)</span> <span class="c1"># A mixed bag. cons is</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">&#39;1 23 [&quot;four&quot; [-5.0] cons] 8888&#39;</span><span class="p">)</span> <span class="c1"># A mixed bag. cons is</span>
<span class="c1"># a Symbol, no lookup at</span>
<span class="c1"># parse-time. Haiku docs.</span>
</pre></div>
@ -170,13 +176,13 @@ like that.</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="p">(</span><span class="mi">23</span><span class="p">,</span> <span class="p">((</span><span class="s1">&#39;four&#39;</span><span class="p">,</span> <span class="p">((</span><span class="o">-</span><span class="mf">5.0</span><span class="p">,</span> <span class="p">()),</span> <span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="p">()))),</span> <span class="p">(</span><span class="mi">8888</span><span class="p">,</span> <span class="p">()))))</span>
</pre></div>
</div>
<div class="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">&#39;[][][][][]&#39;</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">&#39;[][][][][]&#39;</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">&#39;[[[[[]]]]]&#39;</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">&#39;[[[[[]]]]]&#39;</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>
@ -192,7 +198,7 @@ the Joy system. There are simple functions such as addition <code class="docutil
<code class="docutils literal notranslate"><span class="pre">+</span></code>, the library module supports aliases), and combinators which
provide control-flow and higher-order operations.</p>
<p>Many of the functions are defined in Python, like <code class="docutils literal notranslate"><span class="pre">dip</span></code>:</p>
<div class="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>
@ -205,10 +211,11 @@ provide control-flow and higher-order operations.</p>
When the interpreter executes a definition function that function just
pushes its body expression onto the pending expression (the
continuation) and returns control to the interpreter.</p>
<div class="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
@ -241,7 +248,8 @@ anamorphism == [pop []] swap [dip swons] genrec
range == [0 &lt;=] [1 - dup] anamorphism
while == swap [nullary] cons dup dipd concat loop
dudipd == dup dipd
primrec == [i] genrec</pre>
primrec == [i] genrec
</pre>
<p>Currently, theres no function to add new definitions to the dictionary
from “within” Joy code itself. Adding new definitions remains a
meta-interpreter action. You have to do it yourself, in Python, and wash
@ -290,41 +298,37 @@ developing structured processes.</p>
</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>
@ -334,24 +338,25 @@ developing structured processes.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Intro.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -362,7 +367,7 @@ developing structured processes.</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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>Newtons method &#8212; 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" />
@ -29,17 +30,15 @@
<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">Newtons 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">Newtons method</a><a class="headerlink" href="#newtons-method" title="Permalink to this headline"></a></h1>
<p>Lets use the Newton-Raphson method for finding the root of an equation
to write a function that can compute the square root of a number.</p>
<p>Cf. <a class="reference external" href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">“Why Functional Programming Matters” by John
Hughes</a></p>
<div class="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">
@ -91,10 +90,10 @@ function were writing. If we let 1 be the initial approximation:</p>
<span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="mi">23</span> <span class="n">over</span> <span class="o">/</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span><span class="p">]</span> <span class="n">make_generator</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator&#39;</span><span class="p">)</span>
</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">&#39;23 gsra&#39;</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">&#39;23 gsra&#39;</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>
@ -102,7 +101,7 @@ function were writing. If we let 1 be the initial approximation:</p>
</div>
<p>Lets drive the generator a few time (with the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator) and
square the approximation to see how well it works…</p>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;23 gsra 6 [x popd] times first sqr&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;23 gsra 6 [x popd] times first sqr&#39;</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>
@ -115,11 +114,10 @@ square the approximation to see how well it works…</p>
<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
@ -144,7 +142,7 @@ generated already and epsilon ε is handy on the stack…</p>
<span class="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="n">a</span><span class="o">-</span><span class="n">b</span><span class="p">)</span><span class="o">&lt;=</span><span class="n">ε</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;_within_P == [first - abs] dip &lt;=&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;_within_P == [first - abs] dip &lt;=&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
@ -156,7 +154,7 @@ generated already and epsilon ε is handy on the stack…</p>
<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">&#39;_within_B == roll&lt; popop first&#39;</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">&#39;_within_B == roll&lt; popop first&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
@ -166,9 +164,9 @@ generated already and epsilon ε is handy on the stack…</p>
</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>
@ -181,7 +179,7 @@ generated already and epsilon ε is handy on the stack…</p>
<span class="n">b</span> <span class="p">[</span><span class="n">c</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="n">within</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;_within_R == [popd x] dip&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;_within_R == [popd x] dip&#39;</span><span class="p">)</span>
</pre></div>
</div>
</div>
@ -193,31 +191,31 @@ generated already and epsilon ε is handy on the stack…</p>
<span class="n">a</span> <span class="p">[</span><span class="n">b</span> <span class="n">G</span><span class="p">]</span> <span class="n">ε</span> <span class="o">...</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec&#39;</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">&#39;within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec&#39;</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">&#39;sqrt == gsra within&#39;</span><span class="p">)</span>
</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">&#39;36 sqrt&#39;</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">&#39;36 sqrt&#39;</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">&#39;23 sqrt&#39;</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">&#39;23 sqrt&#39;</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>
@ -231,50 +229,28 @@ generated already and epsilon ε is handy on the stack…</p>
</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="#">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Newtons method</a><ul>
<li><a class="reference internal" href="#a-generator-for-approximations">A Generator for Approximations</a><ul>
<li><a class="reference internal" href="#a-function-to-compute-the-next-approximation">A Function to Compute the Next Approximation</a></li>
<li><a class="reference internal" href="#make-it-into-a-generator">Make it into a Generator</a></li>
</ul>
</li>
<li><a class="reference internal" href="#finding-consecutive-approximations-within-a-tolerance">Finding Consecutive Approximations within a Tolerance</a><ul>
<li><a class="reference internal" href="#predicate">Predicate</a></li>
<li><a class="reference internal" href="#base-case">Base-Case</a></li>
<li><a class="reference internal" href="#recur">Recur</a></li>
<li><a class="reference internal" href="#setting-up">Setting up</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -286,24 +262,25 @@ generated already and epsilon ε is handy on the stack…</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Newton-Raphson.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -314,7 +291,7 @@ generated already and epsilon ε is handy on the stack…</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,82 +30,39 @@
<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 doesnt need to change.</p></li>
<li>Joy doesnt need to change.</li>
</ol>
<blockquote>
<div><ol class="upperalpha simple">
<li><p>The interpreter doesnt need to change, <code class="docutils literal notranslate"><span class="pre">viewer</span></code> function can customize mainloop. Or use a sub-interpreter (Joy in Joy.) The base interpreter remains static.</p></li>
<li><p>Once a function has been named and defined <em>never change that name</em>. Its just not allowed. If you need to change a function <code class="docutils literal notranslate"><span class="pre">foo</span></code> you have to call it <code class="docutils literal notranslate"><span class="pre">foo_II</span></code> or something. Once a function (name mapped to behavior) is released to the public <em>thats it</em>, its done.</p></li>
<li><p>The language evolves by adding new definitions and refactoring, always choosing new names for new functions.</p></li>
<li>The interpreter doesnt need to change, <code class="docutils literal notranslate"><span class="pre">viewer</span></code> function can customize mainloop. Or use a sub-interpreter (Joy in Joy.) The base interpreter remains static.</li>
<li>Once a function has been named and defined <em>never change that name</em>. Its just not allowed. If you need to change a function <code class="docutils literal notranslate"><span class="pre">foo</span></code> you have to call it <code class="docutils literal notranslate"><span class="pre">foo_II</span></code> or something. Once a function (name mapped to behavior) is released to the public <em>thats it</em>, its done.</li>
<li>The language evolves by adding new definitions and refactoring, always choosing new names for new functions.</li>
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
@ -115,24 +73,25 @@
</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>
@ -143,7 +102,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="treating-trees-i-ordered-binary-trees">
@ -63,7 +62,7 @@ the Sufficiently Smart Compiler can be modified to use an optimized
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">
@ -100,10 +99,10 @@ functions on otherwise undistinguished Joy datastructures.)</p>
<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">&#39;Tree-new == swap [[] []] cons cons&#39;</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">&#39;Tree-new == swap [[] []] cons cons&#39;</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">&#39;&quot;v&quot; &quot;k&quot; Tree-new&#39;</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">&#39;&quot;v&quot; &quot;k&quot; Tree-new&#39;</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">&#39;k&#39;</span> <span class="s1">&#39;v&#39;</span> <span class="p">[]</span> <span class="p">[]]</span>
@ -159,18 +158,18 @@ comparison operator:</p>
<span class="n">P</span> <span class="o">==</span> <span class="n">pop</span> <span class="n">roll</span><span class="o">&gt;</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">&#39;P == pop roll&gt; pop first&#39;</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">&#39;P == pop roll&gt; pop first&#39;</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">&#39;[&quot;old_key&quot; 23 [] []] 17 &quot;new_key&quot; [&quot;...&quot;] P&#39;</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">&#39;[&quot;old_key&quot; 23 [] []] 17 &quot;new_key&quot; [&quot;...&quot;] P&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;new_key&#39;</span> <span class="s1">&#39;old_key&#39;</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 were adding is greater than the nodes 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 were adding is greater than the nodes 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>
@ -217,24 +216,24 @@ stack:</p>
<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">&#39;T == cons cons [dipdd] cons infra&#39;</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">&#39;T == cons cons [dipdd] cons infra&#39;</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">&#39;[&quot;old_k&quot; &quot;old_value&quot; &quot;left&quot; &quot;right&quot;] &quot;new_value&quot; &quot;new_key&quot; [&quot;Tree-add&quot;] T&#39;</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">&#39;[&quot;old_k&quot; &quot;old_value&quot; &quot;left&quot; &quot;right&quot;] &quot;new_value&quot; &quot;new_key&quot; [&quot;Tree-add&quot;] T&#39;</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">&#39;old_k&#39;</span> <span class="s1">&#39;old_value&#39;</span> <span class="s1">&#39;left&#39;</span> <span class="s1">&#39;Tree-add&#39;</span> <span class="s1">&#39;new_key&#39;</span> <span class="s1">&#39;new_value&#39;</span> <span class="s1">&#39;right&#39;</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 were adding is less than the nodes 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 were adding is less than the nodes 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">&lt;</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">&#39;E == [P &lt;] [Te] [Ee] ifte&#39;</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">&#39;E == [P &lt;] [Te] [Ee] ifte&#39;</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
@ -243,10 +242,10 @@ instead of the right, so the only difference is that it must use
<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">&#39;Te == cons cons [dipd] cons infra&#39;</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">&#39;Te == cons cons [dipd] cons infra&#39;</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">&#39;[&quot;old_k&quot; &quot;old_value&quot; &quot;left&quot; &quot;right&quot;] &quot;new_value&quot; &quot;new_key&quot; [&quot;Tree-add&quot;] Te&#39;</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">&#39;[&quot;old_k&quot; &quot;old_value&quot; &quot;left&quot; &quot;right&quot;] &quot;new_value&quot; &quot;new_key&quot; [&quot;Tree-add&quot;] Te&#39;</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">&#39;old_k&#39;</span> <span class="s1">&#39;old_value&#39;</span> <span class="s1">&#39;Tree-add&#39;</span> <span class="s1">&#39;new_key&#39;</span> <span class="s1">&#39;new_value&#39;</span> <span class="s1">&#39;left&#39;</span> <span class="s1">&#39;right&#39;</span><span class="p">]</span>
@ -274,10 +273,10 @@ instead of the right, so the only difference is that it must use
<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">&#39;Ee == pop swap roll&lt; rest rest cons cons&#39;</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">&#39;Ee == pop swap roll&lt; rest rest cons cons&#39;</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">&#39;[&quot;k&quot; &quot;old_value&quot; &quot;left&quot; &quot;right&quot;] &quot;new_value&quot; &quot;k&quot; [&quot;Tree-add&quot;] Ee&#39;</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">&#39;[&quot;k&quot; &quot;old_value&quot; &quot;left&quot; &quot;right&quot;] &quot;new_value&quot; &quot;k&quot; [&quot;Tree-add&quot;] Ee&#39;</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">&#39;k&#39;</span> <span class="s1">&#39;new_value&#39;</span> <span class="s1">&#39;left&#39;</span> <span class="s1">&#39;right&#39;</span><span class="p">]</span>
@ -302,43 +301,43 @@ instead of the right, so the only difference is that it must use
<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">&#39;Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P &gt;] [T] [E] ifte] genrec&#39;</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">&#39;Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P &gt;] [T] [E] ifte] genrec&#39;</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">&#39;[] 23 &quot;b&quot; Tree-add&#39;</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">&#39;[] 23 &quot;b&quot; Tree-add&#39;</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">&#39;b&#39;</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">&#39;[&quot;b&quot; 23 [] []] 88 &quot;c&quot; Tree-add&#39;</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">&#39;[&quot;b&quot; 23 [] []] 88 &quot;c&quot; Tree-add&#39;</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">&#39;b&#39;</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">&#39;c&#39;</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">&#39;[&quot;b&quot; 23 [] []] 88 &quot;a&quot; Tree-add&#39;</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">&#39;[&quot;b&quot; 23 [] []] 88 &quot;a&quot; Tree-add&#39;</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">&#39;b&#39;</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">&#39;a&#39;</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">&#39;[&quot;b&quot; 23 [] []] 88 &quot;b&quot; Tree-add&#39;</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">&#39;[&quot;b&quot; 23 [] []] 88 &quot;b&quot; Tree-add&#39;</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">&#39;b&#39;</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">&#39;[] 23 &quot;b&quot; Tree-add 88 &quot;a&quot; Tree-add 44 &quot;c&quot; Tree-add&#39;</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">&#39;[] 23 &quot;b&quot; Tree-add 88 &quot;a&quot; Tree-add 44 &quot;c&quot; Tree-add&#39;</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">&#39;b&#39;</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">&#39;a&#39;</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">&#39;c&#39;</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">&#39;[] [[23 &quot;b&quot;] [88 &quot;a&quot;] [44 &quot;c&quot;]] [i Tree-add] step&#39;</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">&#39;[] [[23 &quot;b&quot;] [88 &quot;a&quot;] [44 &quot;c&quot;]] [i Tree-add] step&#39;</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">&#39;b&#39;</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">&#39;a&#39;</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">&#39;c&#39;</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
@ -365,19 +364,19 @@ values:</p>
<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">&quot;1 0 [&#39;G&#39;] [&#39;E&#39;] [&#39;L&#39;] cmp&quot;</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">&quot;1 0 [&#39;G&#39;] [&#39;E&#39;] [&#39;L&#39;] cmp&quot;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;G&#39;</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">&quot;1 1 [&#39;G&#39;] [&#39;E&#39;] [&#39;L&#39;] cmp&quot;</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">&quot;1 1 [&#39;G&#39;] [&#39;E&#39;] [&#39;L&#39;] cmp&quot;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;E&#39;</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">&quot;0 1 [&#39;G&#39;] [&#39;E&#39;] [&#39;L&#39;] cmp&quot;</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">&quot;0 1 [&#39;G&#39;] [&#39;E&#39;] [&#39;L&#39;] cmp&quot;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;L&#39;</span>
@ -414,7 +413,7 @@ node key (by throwing everything else away):</p>
<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">&#39;P == over [popop popop first] nullary&#39;</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">&#39;P == over [popop popop first] nullary&#39;</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
@ -434,10 +433,10 @@ to understand:</p>
<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">&#39;Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec&#39;</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">&#39;Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec&#39;</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">&#39;[] 23 &quot;b&quot; Tree-add 88 &quot;a&quot; Tree-add 44 &quot;c&quot; Tree-add&#39;</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">&#39;[] 23 &quot;b&quot; Tree-add 88 &quot;a&quot; Tree-add 44 &quot;c&quot; Tree-add&#39;</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">&#39;b&#39;</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">&#39;a&#39;</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">&#39;c&#39;</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
@ -545,22 +544,22 @@ with an interesting situation:</p>
<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">&lt;</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">&#39;Tree-iter == [not] [pop] roll&lt; [dupdip rest rest] cons [step] genrec&#39;</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">&#39;Tree-iter == [not] [pop] roll&lt; [dupdip rest rest] cons [step] genrec&#39;</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">&#39;[] [foo] Tree-iter&#39;</span><span class="p">)</span> <span class="c1"># It doesn&#39;t matter what F is as it won&#39;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">&#39;[] [foo] Tree-iter&#39;</span><span class="p">)</span> <span class="c1"># It doesn&#39;t matter what F is as it won&#39;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">&quot;[&#39;b&#39; 23 [&#39;a&#39; 88 [] []] [&#39;c&#39; 44 [] []]] [first] Tree-iter&quot;</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">&quot;[&#39;b&#39; 23 [&#39;a&#39; 88 [] []] [&#39;c&#39; 44 [] []]] [first] Tree-iter&quot;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;b&#39;</span> <span class="s1">&#39;a&#39;</span> <span class="s1">&#39;c&#39;</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">&quot;[&#39;b&#39; 23 [&#39;a&#39; 88 [] []] [&#39;c&#39; 44 [] []]] [second] Tree-iter&quot;</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">&quot;[&#39;b&#39; 23 [&#39;a&#39; 88 [] []] [&#39;c&#39; 44 [] []]] [second] Tree-iter&quot;</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>
@ -571,20 +570,20 @@ with an interesting situation:</p>
<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. Its set-like in that duplicate items added
to e.g.&nbsp;0 and ignoring them. Its 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> &lt;<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>&gt;`__
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">&#39;[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step&#39;</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">&#39;[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step&#39;</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">&#39;to_set == [] swap [0 swap Tree-add] step&#39;</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">&#39;to_set == [] swap [0 swap Tree-add] step&#39;</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">&#39;[3 9 5 2 8 6 7 8 4] to_set&#39;</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">&#39;[3 9 5 2 8 6 7 8 4] to_set&#39;</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>
@ -592,10 +591,10 @@ time.</p>
</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">&#39;unique == [to_set [first] Tree-iter] cons run&#39;</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">&#39;unique == [to_set [first] Tree-iter] cons run&#39;</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">&#39;[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique&#39;</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">&#39;[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique&#39;</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>
@ -641,8 +640,8 @@ when they run:</p>
</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>
@ -679,7 +678,7 @@ right side:</p>
</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(&#39;Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec&#39;)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#define(&#39;Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec&#39;)</span>
<span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">&#39;&#39;&#39;</span>
@ -695,7 +694,7 @@ right side:</p>
<span class="s1">&#39;&#39;&#39;</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">&#39;[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order&#39;</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">&#39;[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order&#39;</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>
@ -835,7 +834,7 @@ because theres no value to discard.</p>
<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">&gt;</span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o">&lt;</span><span class="p">]</span> <span class="nb">cmp</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># I don&#39;t want to deal with name conflicts with the above so I&#39;m inlining everything here.</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># I don&#39;t want to deal with name conflicts with the above so I&#39;m inlining everything here.</span>
<span class="c1"># The original Joy system has &quot;hide&quot; 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&#39;t want to implement</span>
<span class="c1"># that (yet) so...</span>
@ -852,19 +851,19 @@ because theres no value to discard.</p>
<span class="s1">&#39;&#39;&#39;</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">&#39;[&quot;gary&quot; 23 [] []] &quot;mike&quot; [popd &quot; not in tree&quot; +] Tree-get&#39;</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">&#39;[&quot;gary&quot; 23 [] []] &quot;mike&quot; [popd &quot; not in tree&quot; +] Tree-get&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;mike not in tree&#39;</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">&#39;[&quot;gary&quot; 23 [] []] &quot;gary&quot; [popop &quot;err&quot;] Tree-get&#39;</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">&#39;[&quot;gary&quot; 23 [] []] &quot;gary&quot; [popop &quot;err&quot;] Tree-get&#39;</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">&#39;&#39;&#39;</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">&#39;&#39;&#39;</span>
<span class="s1"> [] [[0 &#39;a&#39;] [1 &#39;b&#39;] [2 &#39;c&#39;]] [i Tree-add] step</span>
@ -876,7 +875,7 @@ because theres no value to discard.</p>
<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">&#39;&#39;&#39;</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">&#39;&#39;&#39;</span>
<span class="s1"> [] [[0 &#39;a&#39;] [1 &#39;b&#39;] [2 &#39;c&#39;]] [i Tree-add] step</span>
@ -1175,7 +1174,7 @@ E == [
</div>
<p>By the standards of the code Ive 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">&#39;&#39;&#39;</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">&#39;&#39;&#39;</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>
@ -1193,43 +1192,43 @@ program.</p>
<span class="s1">&#39;&#39;&#39;</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">&quot;[&#39;a&#39; 23 [] [&#39;b&#39; 88 [] [&#39;c&#39; 44 [] []]]] &#39;c&#39; Tree-Delete &quot;</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">&quot;[&#39;a&#39; 23 [] [&#39;b&#39; 88 [] [&#39;c&#39; 44 [] []]]] &#39;c&#39; Tree-Delete &quot;</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">&#39;a&#39;</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">&#39;b&#39;</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">&quot;[&#39;a&#39; 23 [] [&#39;b&#39; 88 [] [&#39;c&#39; 44 [] []]]] &#39;b&#39; Tree-Delete &quot;</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">&quot;[&#39;a&#39; 23 [] [&#39;b&#39; 88 [] [&#39;c&#39; 44 [] []]]] &#39;b&#39; Tree-Delete &quot;</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">&#39;a&#39;</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">&#39;c&#39;</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">&quot;[&#39;a&#39; 23 [] [&#39;b&#39; 88 [] [&#39;c&#39; 44 [] []]]] &#39;a&#39; Tree-Delete &quot;</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">&quot;[&#39;a&#39; 23 [] [&#39;b&#39; 88 [] [&#39;c&#39; 44 [] []]]] &#39;a&#39; Tree-Delete &quot;</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">&#39;b&#39;</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">&#39;c&#39;</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">&quot;[&#39;a&#39; 23 [] [&#39;b&#39; 88 [] [&#39;c&#39; 44 [] []]]] &#39;der&#39; Tree-Delete &quot;</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">&quot;[&#39;a&#39; 23 [] [&#39;b&#39; 88 [] [&#39;c&#39; 44 [] []]]] &#39;der&#39; Tree-Delete &quot;</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">&#39;a&#39;</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">&#39;b&#39;</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">&#39;c&#39;</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">&#39;[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step&#39;</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">&#39;[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step&#39;</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">&quot;[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete &quot;</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">&quot;[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete &quot;</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">&quot;[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete &quot;</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">&quot;[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete &quot;</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>
@ -1289,50 +1288,86 @@ Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
<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 were adding is greater than the nodes key.</a></li>
<li><a class="reference internal" href="#if-the-key-were-adding-is-less-than-the-nodes-key">If the key were adding is less than the nodes 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>
@ -1344,24 +1379,25 @@ Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec
</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>
@ -1372,7 +1408,7 @@ Tree-delete == [pop not] [pop] [_Tree_delete_R0] [_Tree_delete_R1] genrec
</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>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,11 +30,9 @@
<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">
@ -99,11 +98,11 @@ the variables:</p>
</div>
<p>The three arguments are to the left, so we can “chop off” everything to
the right and say its the definition of the <code class="docutils literal notranslate"><span class="pre">quadratic</span></code> function:</p>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Lets 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">&#39;3 1 1 quadratic&#39;</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">&#39;3 1 1 quadratic&#39;</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>
@ -113,7 +112,7 @@ the right and say its the definition of the <code class="docutils literal not
lines are the <code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">dipd</span></code> combinators building the main program
by incorporating the values on the stack. Then that program runs and you
get the results. This is pretty typical of Joy code.</p>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;-5 1 4 quadratic&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;-5 1 4 quadratic&#39;</span><span class="p">)</span>
</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>
@ -168,50 +167,25 @@ get the results. This is pretty typical of Joy code.</p>
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
<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>
@ -223,24 +197,25 @@ get the results. This is pretty typical of Joy code.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Quadratic.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -251,7 +226,7 @@ get the results. This is pretty typical of Joy code.</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,11 +30,9 @@
<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">
@ -47,18 +46,16 @@ several generic specializations.</p>
</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
@ -93,16 +90,16 @@ have to do to apply the quoted <code class="docutils literal notranslate"><span
is a recursive function <code class="docutils literal notranslate"><span class="pre">H</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">C</span></code> that converts a value of type
<code class="docutils literal notranslate"><span class="pre">A</span></code> into a value of type <code class="docutils literal notranslate"><span class="pre">C</span></code> by means of:</p>
<ul class="simple">
<li><p>A generator <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">(B,</span> <span class="pre">A)</span></code></p></li>
<li><p>A combiner <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">::</span> <span class="pre">(B,</span> <span class="pre">C)</span> <span class="pre">-&gt;</span> <span class="pre">C</span></code></p></li>
<li><p>A predicate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">Bool</span></code> to detect the base case</p></li>
<li><p>A base case value <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">::</span> <span class="pre">C</span></code></p></li>
<li><p>Recursive calls (zero or more); it has a “call stack in the form of a
cons list”.</p></li>
<li>A generator <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">(B,</span> <span class="pre">A)</span></code></li>
<li>A combiner <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">::</span> <span class="pre">(B,</span> <span class="pre">C)</span> <span class="pre">-&gt;</span> <span class="pre">C</span></code></li>
<li>A predicate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-&gt;</span> <span class="pre">Bool</span></code> to detect the base case</li>
<li>A base case value <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">::</span> <span class="pre">C</span></code></li>
<li>Recursive calls (zero or more); it has a “call stack in the form of a
cons list”.</li>
</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">&#39;&#39;&#39;Return a hylomorphism function H.&#39;&#39;&#39;</span>
<span class="k">def</span> <span class="nf">H</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
@ -170,9 +167,9 @@ arguments out of the pieces given to the <code class="docutils literal notransla
</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>
@ -186,7 +183,7 @@ the left so we have a definition for <code class="docutils literal notranslate">
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">hylomorphism</span> <span class="o">==</span> <span class="p">[</span><span class="n">unit</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="n">swoncat</span><span class="p">]</span> <span class="n">dipd</span> <span class="p">[</span><span class="n">dip</span><span class="p">]</span> <span class="n">swoncat</span> <span class="n">genrec</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="section" id="example-finding-triangular-numbers">
@ -196,22 +193,22 @@ of all positive integers less than that one. (In this case the types
<code class="docutils literal notranslate"><span class="pre">A</span></code>, <code class="docutils literal notranslate"><span class="pre">B</span></code> and <code class="docutils literal notranslate"><span class="pre">C</span></code> are all <code class="docutils literal notranslate"><span class="pre">int</span></code>.)</p>
<p>To sum a range of integers from 0 to <em>n</em> - 1:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">[P]</span></code> is <code class="docutils literal notranslate"><span class="pre">[1</span> <span class="pre">&lt;=]</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">c</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">[G]</span></code> is <code class="docutils literal notranslate"><span class="pre">[--</span> <span class="pre">dup]</span></code></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">[F]</span></code> is <code class="docutils literal notranslate"><span class="pre">[+]</span></code></p></li>
<li><code class="docutils literal notranslate"><span class="pre">[P]</span></code> is <code class="docutils literal notranslate"><span class="pre">[1</span> <span class="pre">&lt;=]</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">c</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">[G]</span></code> is <code class="docutils literal notranslate"><span class="pre">[--</span> <span class="pre">dup]</span></code></li>
<li><code class="docutils literal notranslate"><span class="pre">[F]</span></code> is <code class="docutils literal notranslate"><span class="pre">[+]</span></code></li>
</ul>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;triangular_number == [1 &lt;=] 0 [-- dup] [+] hylomorphism&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;triangular_number == [1 &lt;=] 0 [-- dup] [+] hylomorphism&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Lets 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">&#39;5 triangular_number&#39;</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">&#39;5 triangular_number&#39;</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">&#39;[0 1 2 3 4 5 6] [triangular_number] map&#39;</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">&#39;[0 1 2 3 4 5 6] [triangular_number] map&#39;</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>
@ -363,10 +360,8 @@ values.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">A</span> <span class="o">==</span> <span class="p">[</span><span class="n">P</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="n">G</span><span class="p">]</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
<div class="section" id="range-et-al">
<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.&nbsp;An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.<a class="headerlink" href="#range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n" title="Permalink to this headline"></a></h3>
<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">
@ -375,10 +370,10 @@ the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</p>
<span class="o">==</span> <span class="p">[</span><span class="mi">0</span> <span class="o">&lt;=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;range == [0 &lt;=] [] [-- dup] [swons] hylomorphism&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;range == [0 &lt;=] [] [-- dup] [swons] hylomorphism&#39;</span><span class="p">)</span>
</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">&#39;5 range&#39;</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">&#39;5 range&#39;</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>
@ -391,10 +386,10 @@ the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</p>
<span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="mi">0</span> <span class="o">&lt;=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">primrec</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;range_reverse == [] swap [0 &lt;=] [pop] [-- dup [swons] dip] primrec&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;range_reverse == [] swap [0 &lt;=] [pop] [-- dup [swons] dip] primrec&#39;</span><span class="p">)</span>
</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">&#39;5 range_reverse&#39;</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">&#39;5 range_reverse&#39;</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>
@ -407,10 +402,10 @@ the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</p>
<span class="o">==</span> <span class="p">[</span><span class="mi">0</span> <span class="o">&lt;=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[[</span><span class="o">--</span><span class="p">]</span> <span class="n">dupdip</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;ranger == [0 &lt;=] [pop []] [[--] dupdip] [dip swons] genrec&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;ranger == [0 &lt;=] [pop []] [[--] dupdip] [dip swons] genrec&#39;</span><span class="p">)</span>
</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">&#39;5 ranger&#39;</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">&#39;5 ranger&#39;</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>
@ -423,10 +418,10 @@ the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</p>
<span class="o">==</span> <span class="p">[]</span> <span class="n">swap</span> <span class="p">[</span><span class="mi">0</span> <span class="o">&lt;=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dupdip</span> <span class="o">--</span><span class="p">]</span> <span class="n">primrec</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;ranger_reverse == [] swap [0 &lt;=] [pop] [[swons] dupdip --] primrec&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;ranger_reverse == [] swap [0 &lt;=] [pop] [[swons] dupdip --] primrec&#39;</span><span class="p">)</span>
</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">&#39;5 ranger_reverse&#39;</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">&#39;5 ranger_reverse&#39;</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>
@ -447,17 +442,17 @@ and makes some new value.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">C</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="n">c</span> <span class="p">[</span><span class="n">uncons</span> <span class="n">swap</span><span class="p">]</span> <span class="p">[</span><span class="n">F</span><span class="p">]</span> <span class="n">hylomorphism</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;swuncons == uncons swap&#39;</span><span class="p">)</span> <span class="c1"># Awkward name.</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;swuncons == uncons swap&#39;</span><span class="p">)</span> <span class="c1"># Awkward name.</span>
</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">&#39;sum == [not] 0 [swuncons] [+] hylomorphism&#39;</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">&#39;sum == [not] 0 [swuncons] [+] hylomorphism&#39;</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">&#39;[5 4 3 2 1] sum&#39;</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">&#39;[5 4 3 2 1] sum&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
@ -467,7 +462,7 @@ and makes some new value.</p>
<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">&#39;[step] help&#39;</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">&#39;[step] help&#39;</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>
@ -491,10 +486,10 @@ and makes some new value.</p>
<span class="n">on</span> <span class="n">top</span> <span class="n">of</span> <span class="n">the</span> <span class="n">stack</span><span class="o">.</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;sum == 0 swap [+] step&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;sum == 0 swap [+] step&#39;</span><span class="p">)</span>
</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">&#39;[5 4 3 2 1] sum&#39;</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">&#39;[5 4 3 2 1] sum&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
@ -515,10 +510,10 @@ and makes some new value.</p>
<span class="n">P</span> <span class="o">==</span> <span class="mi">1</span> <span class="o">&lt;=</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;factorial == 1 swap [1 &lt;=] [pop] [[*] dupdip --] primrec&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;factorial == 1 swap [1 &lt;=] [pop] [[*] dupdip --] primrec&#39;</span><span class="p">)</span>
</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">&#39;5 factorial&#39;</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">&#39;5 factorial&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">120</span>
@ -547,10 +542,10 @@ pattern <code class="docutils literal notranslate"><span class="pre">H2</span></
<span class="n">P</span> <span class="o">==</span> <span class="ow">not</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;tails == [] swap [not] [pop] [rest dup [swons] dip] primrec&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;tails == [] swap [not] [pop] [rest dup [swons] dip] primrec&#39;</span><span class="p">)</span>
</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">&#39;[1 2 3] tails&#39;</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">&#39;[1 2 3] tails&#39;</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>
@ -594,50 +589,53 @@ Wire”</a></p>
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Recursion Combinators</a><ul>
<li><a class="reference internal" href="#designing-recursive-functions">Designing Recursive Functions</a></li>
<li><a class="reference internal" href="#primitive-recursive-functions">Primitive Recursive Functions</a></li>
<li><a class="reference internal" href="#hylomorphism">Hylomorphism</a></li>
<li><a class="reference internal" href="#hylomorphism-in-joy">Hylomorphism in Joy</a></li>
<li><a class="reference internal" href="#derivation-of-hylomorphism-combinator">Derivation of <code class="docutils literal notranslate"><span class="pre">hylomorphism</span></code> combinator</a><ul>
<li><a class="reference internal" href="#example-finding-triangular-numbers">Example: Finding Triangular Numbers</a></li>
</ul>
</li>
<li><a class="reference internal" href="#four-specializations">Four Specializations</a><ul>
<li><a class="reference internal" href="#h1"><code class="docutils literal notranslate"><span class="pre">H1</span></code></a></li>
<li><a class="reference internal" href="#h2"><code class="docutils literal notranslate"><span class="pre">H2</span></code></a></li>
<li><a class="reference internal" href="#h3"><code class="docutils literal notranslate"><span class="pre">H3</span></code></a></li>
<li><a class="reference internal" href="#h4"><code class="docutils literal notranslate"><span class="pre">H4</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#anamorphism">Anamorphism</a><ul>
<li><a class="reference internal" href="#range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n"><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al.&nbsp;An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</a><ul>
<li><a class="reference internal" href="#range-with-h1"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H1</span></code></a></li>
<li><a class="reference internal" href="#range-with-h2"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H2</span></code></a></li>
<li><a class="reference internal" href="#range-with-h3"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H3</span></code></a></li>
<li><a class="reference internal" href="#range-with-h4"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H4</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#catamorphism">Catamorphism</a><ul>
<li><a class="reference internal" href="#the-step-combinator">The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator</a></li>
</ul>
</li>
<li><a class="reference internal" href="#example-factorial-function">Example: Factorial Function</a></li>
<li><a class="reference internal" href="#example-tails">Example: <code class="docutils literal notranslate"><span class="pre">tails</span></code></a></li>
<li><a class="reference internal" href="#conclusion-patterns-of-recursion">Conclusion: Patterns of Recursion</a><ul>
<li><a class="reference internal" href="#hylo-ana-cata">Hylo-, Ana-, Cata-</a></li>
<li><a class="reference internal" href="#para">Para-, ?-, ?-</a></li>
</ul>
</li>
<li><a class="reference internal" href="#appendix-fun-with-symbols">Appendix: Fun with Symbols</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -649,24 +647,25 @@ Wire”</a></p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Recursion_Combinators.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -677,7 +676,7 @@ Wire”</a></p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="replacing-functions-in-the-dictionary">
@ -38,16 +37,16 @@
<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.&nbsp;a function that adds new functions to the
dictionary. However, theres no function that does that. Adding a new
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.</p>
<div class="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">&#39;[23 18] average&#39;</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">&#39;[23 18] average&#39;</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>
@ -105,8 +104,8 @@ it in Python, not Joy.</p>
<p>An efficient <code class="docutils literal notranslate"><span class="pre">sum</span></code> function is already in the library. But for
<code class="docutils literal notranslate"><span class="pre">size</span></code> we can use a “compiled” version hand-written in Python to speed
up evaluation and make the trace more readable.</p>
<div class="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>
@ -121,14 +120,14 @@ up evaluation and make the trace more readable.</p>
</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">&#39;size&#39;</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">&#39;size&#39;</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">&#39;[23 18] average&#39;</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">&#39;[23 18] average&#39;</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>
@ -167,50 +166,19 @@ and re-evaluate the expression.</p>
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
<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>
@ -222,24 +190,25 @@ and re-evaluate the expression.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Replacing.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -250,7 +219,7 @@ and re-evaluate the expression.</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<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">
@ -38,10 +37,10 @@
<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>
@ -202,7 +201,7 @@ difficulty in this sort of thing is orchestrating the recombining
(“join” or “wait”) of the results of the functions after they finish.</p>
<p>The current implementaions and the following definitions <em>are not
actually parallel</em> (yet), but there is no reason they couldnt be
reimplemented in terms of e.g. Python threads. I am not concerned with
reimplemented in terms of e.g.&nbsp;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">
@ -267,7 +266,7 @@ value.)</p>
</pre></div>
</div>
<p>There is no reason why the implementation of <code class="docutils literal notranslate"><span class="pre">map</span></code> couldnt distribute
the <code class="docutils literal notranslate"><span class="pre">Q</span></code> function over e.g. a pool of worker CPUs.</p>
the <code class="docutils literal notranslate"><span class="pre">Q</span></code> function over e.g.&nbsp;a pool of worker CPUs.</p>
</div>
<div class="section" id="pam">
<h3><code class="docutils literal notranslate"><span class="pre">pam</span></code><a class="headerlink" href="#pam" title="Permalink to this headline"></a></h3>
@ -320,50 +319,37 @@ evaluation, yeah?)</p>
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
<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>
@ -375,24 +361,25 @@ evaluation, yeah?)</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/The_Four_Operations.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -403,7 +390,7 @@ evaluation, yeah?)</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="treating-trees-ii-treestep">
@ -148,10 +147,10 @@ the desired outcome.</p>
</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">&#39;&#39;&#39;</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">&#39;&#39;&#39;</span>
<span class="s1"> _treestep_0 == [[not] swap] dip</span>
<span class="s1"> _treestep_1 == [dip] cons [uncons] swoncat</span>
@ -169,7 +168,7 @@ all nodes in a tree with this function:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">sumtree</span> <span class="o">==</span> <span class="p">[</span><span class="n">pop</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="nb">sum</span> <span class="o">+</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;sumtree == [pop 0] [] [sum +] treestep&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;sumtree == [pop 0] [] [sum +] treestep&#39;</span><span class="p">)</span>
</pre></div>
</div>
<p>Running this function on an empty tree value gives zero:</p>
@ -178,7 +177,7 @@ all nodes in a tree with this function:</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">&#39;[] sumtree&#39;</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">&#39;[] sumtree&#39;</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>
@ -192,61 +191,61 @@ all nodes in a tree with this function:</p>
<span class="n">n</span><span class="o">+</span><span class="n">m</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[23] sumtree&#39;</span><span class="p">)</span> <span class="c1"># No child trees.</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[23] sumtree&#39;</span><span class="p">)</span> <span class="c1"># No child trees.</span>
</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">&#39;[23 []] sumtree&#39;</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">&#39;[23 []] sumtree&#39;</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">&#39;[23 [2 [4]] [3]] sumtree&#39;</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">&#39;[23 [2 [4]] [3]] sumtree&#39;</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">&#39;[23 [2 [8] [9]] [3] [4 []]] sumtree&#39;</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">&#39;[23 [2 [8] [9]] [3] [4 []]] sumtree&#39;</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">&#39;[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep&#39;</span><span class="p">)</span> <span class="c1"># Alternate &quot;spelling&quot;.</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep&#39;</span><span class="p">)</span> <span class="c1"># Alternate &quot;spelling&quot;.</span>
</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">&#39;[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep&#39;</span><span class="p">)</span> <span class="c1"># Replace each node.</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep&#39;</span><span class="p">)</span> <span class="c1"># Replace each node.</span>
</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">&#39;[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep&#39;</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">&#39;[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep&#39;</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">&#39;[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree&#39;</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">&#39;[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree&#39;</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">&#39;[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep&#39;</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep&#39;</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
</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">&#39;[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep&#39;</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep&#39;</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span>
@ -277,7 +276,7 @@ all nodes in a tree with this function:</p>
</pre></div>
</div>
<p>This doesnt 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">&#39;[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] [&quot;B&quot;] [first] [i] treestep&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] [&quot;B&quot;] [first] [i] treestep&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="s1">&#39;B&#39;</span> <span class="s1">&#39;B&#39;</span>
@ -299,7 +298,7 @@ depositing our results directly on the stack.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="p">[</span><span class="n">flatten</span> <span class="n">cons</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep&#39;</span><span class="p">)</span>
</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>
@ -322,7 +321,7 @@ depositing our results directly on the stack.</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[]</span> <span class="p">[</span><span class="n">i</span> <span class="n">roll</span><span class="o">&lt;</span> <span class="n">swons</span> <span class="n">concat</span><span class="p">]</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="n">treestep</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll&lt; swons concat] treestep&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll&lt; swons concat] treestep&#39;</span><span class="p">)</span>
</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>
@ -343,7 +342,7 @@ non-empty node is:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">key</span> <span class="n">value</span><span class="p">]</span> <span class="n">N</span> <span class="p">[</span><span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="p">[</span><span class="n">K</span><span class="p">]</span> <span class="n">C</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[[&quot;key&quot; &quot;value&quot;] [&quot;left&quot;] [&quot;right&quot;] ] [&quot;B&quot;] [&quot;N&quot;] [&quot;C&quot;] treegrind&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[[&quot;key&quot; &quot;value&quot;] [&quot;left&quot;] [&quot;right&quot;] ] [&quot;B&quot;] [&quot;N&quot;] [&quot;C&quot;] treegrind&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">&#39;key&#39;</span> <span class="s1">&#39;value&#39;</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[[</span><span class="s1">&#39;left&#39;</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;right&#39;</span><span class="p">]]</span> <span class="p">[[</span><span class="ow">not</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;B&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">uncons</span> <span class="p">[</span><span class="s1">&#39;N&#39;</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;C&#39;</span><span class="p">]</span> <span class="n">genrec</span><span class="p">]</span> <span class="s1">&#39;C&#39;</span>
@ -353,21 +352,21 @@ non-empty node is:</p>
<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">&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [&quot;N&quot;] [step] treegrind&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [&quot;N&quot;] [step] treegrind&#39;</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">&#39;N&#39;</span>
</pre></div>
</div>
<p>Sum the nodes keys.</p>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind&#39;</span><span class="p">)</span>
</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">&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind&#39;</span><span class="p">)</span>
</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>
@ -449,7 +448,7 @@ equal):</p>
</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">&#39;&#39;&#39;</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">&#39;&#39;&#39;</span>
<span class="s1"> T&gt; == pop [first] dip i</span>
<span class="s1"> T&lt; == pop [second] dip i</span>
@ -461,7 +460,7 @@ equal):</p>
<span class="s1">&#39;&#39;&#39;</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">&#39;&#39;&#39;</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">&#39;&#39;&#39;</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>
@ -473,7 +472,7 @@ equal):</p>
<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">&#39;&#39;&#39;</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">&#39;&#39;&#39;</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>
@ -490,50 +489,37 @@ equal):</p>
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a><ul>
<li><a class="reference internal" href="#derive-the-recursive-function">Derive the recursive function.</a></li>
<li><a class="reference internal" href="#extract-the-givens-to-parameterize-the-program">Extract the givens to parameterize the program.</a><ul>
<li><a class="reference internal" href="#alternate-extract-the-givens-to-parameterize-the-program">(alternate) Extract the givens to parameterize the program.</a></li>
</ul>
</li>
<li><a class="reference internal" href="#define-treestep">Define <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
<li><a class="reference internal" href="#examples">Examples</a></li>
<li><a class="reference internal" href="#redefining-the-ordered-binary-tree-in-terms-of-treestep">Redefining the Ordered Binary Tree in terms of <code class="docutils literal notranslate"><span class="pre">treestep</span></code>.</a><ul>
<li><a class="reference internal" href="#traversal">Traversal</a></li>
<li><a class="reference internal" href="#in-order-traversal">In-order traversal</a></li>
</ul>
</li>
<li><a class="reference internal" href="#with-treegrind">With <code class="docutils literal notranslate"><span class="pre">treegrind</span></code>?</a></li>
<li><a class="reference internal" href="#treegrind-with-step"><code class="docutils literal notranslate"><span class="pre">treegrind</span></code> with <code class="docutils literal notranslate"><span class="pre">step</span></code></a></li>
<li><a class="reference internal" href="#do-we-have-the-flexibility-to-reimplement-tree-get">Do we have the flexibility to reimplement <code class="docutils literal notranslate"><span class="pre">Tree-get</span></code>?</a><ul>
<li><a class="reference internal" href="#the-predicate-p">The predicate <code class="docutils literal notranslate"><span class="pre">P</span></code></a></li>
<li><a class="reference internal" href="#e"><code class="docutils literal notranslate"><span class="pre">E</span></code></a></li>
<li><a class="reference internal" href="#t-and-t"><code class="docutils literal notranslate"><span class="pre">T&lt;</span></code> and <code class="docutils literal notranslate"><span class="pre">T&gt;</span></code></a></li>
</ul>
</li>
<li><a class="reference internal" href="#putting-it-together">Putting it together</a></li>
</ul>
</li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
@ -545,24 +531,25 @@ equal):</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Treestep.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -573,7 +560,7 @@ equal):</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,13 +30,11 @@
<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">&#39;</span><span class="si">%(message)s</span><span class="s1">&#39;</span><span class="p">,</span>
@ -44,7 +43,7 @@
<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>
@ -54,14 +53,14 @@
<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">&#39;product&#39;</span><span class="p">]</span>
<span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">D</span><span class="p">)</span>
</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
@ -72,31 +71,31 @@
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">&#39;0 1 2 [3 4]&#39;</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">&#39;0 1 2 [3 4]&#39;</span><span class="p">)</span> <span class="c1"># reverse order</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</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>
@ -106,17 +105,17 @@
</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">&#39;[2 3]&#39;</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">&#39;[2 3]&#39;</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>
@ -126,7 +125,7 @@
</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
@ -135,14 +134,14 @@
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">&#39;&quot;two&quot;&#39;</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">&#39;&quot;two&quot;&#39;</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</pre></div>
</div>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">&#39;two&#39;</span>
</pre></div>
</div>
<div class="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>
@ -156,50 +155,19 @@
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
<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>
@ -211,24 +179,25 @@
</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>
@ -239,7 +208,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="traversing-datastructures-with-zippers">
@ -42,18 +41,17 @@ the original paper: <a class="reference external" href="https://www.st.cs.uni-sa
Huet</a></p>
<p>Given a datastructure on the stack we can navigate through it, modify
it, and rebuild it using the “zipper” technique.</p>
<div class="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 arent any complex datastructures, just ints, floats,
strings, Symbols (strings that are names of functions) and sequences
(aka lists, aka quoted literals, aka aggregates, etc…), but we can
build
(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">&#39;[1 [2 [3 4 25 6] 7] 8]&#39;</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">&#39;[1 [2 [3 4 25 6] 7] 8]&#39;</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>
@ -76,13 +74,13 @@ datastructure used to keep track of these items is the zipper.)</p>
show the trace so you can see how it works. If we were going to use
these a lot it would make sense to write Python versions for efficiency,
but see below.</p>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;z-down == [] swap uncons swap&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;z-down == [] swap uncons swap&#39;</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">&#39;z-up == swons swap shunt&#39;</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">&#39;z-right == [swons] cons dip uncons swap&#39;</span><span class="p">)</span>
<span class="n">define</span><span class="p">(</span><span class="s1">&#39;z-left == swons [uncons swap] dip swap&#39;</span><span class="p">)</span>
</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">&#39;[1 [2 [3 4 25 6] 7] 8] z-down&#39;</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">&#39;[1 [2 [3 4 25 6] 7] 8] z-down&#39;</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>
@ -94,7 +92,7 @@ but see below.</p>
<span class="p">[]</span> <span class="p">[[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="mi">1</span> <span class="o">.</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;[] [[2 [3 4 25 6] 7] 8] 1 z-right&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">&#39;[] [[2 [3 4 25 6] 7] 8] 1 z-right&#39;</span><span class="p">)</span>
</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>
@ -114,43 +112,43 @@ but see below.</p>
<span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[1] [8] [2 [3 4 25 6] 7] z-down&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[1] [8] [2 [3 4 25 6] 7] z-down&#39;</span><span class="p">)</span>
</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">&#39;[1] [8] [] [[3 4 25 6] 7] 2 z-right&#39;</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">&#39;[1] [8] [] [[3 4 25 6] 7] 2 z-right&#39;</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">&#39;[1] [8] [2] [7] [3 4 25 6] z-down&#39;</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">&#39;[1] [8] [2] [7] [3 4 25 6] z-down&#39;</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">&#39;[1] [8] [2] [7] [] [4 25 6] 3 z-right&#39;</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">&#39;[1] [8] [2] [7] [] [4 25 6] 3 z-right&#39;</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">&#39;[1] [8] [2] [7] [3] [25 6] 4 z-right&#39;</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">&#39;[1] [8] [2] [7] [3] [25 6] 4 z-right&#39;</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">&#39;[1] [8] [2] [7] [4 3] [6] 25 sqr&#39;</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">&#39;[1] [8] [2] [7] [4 3] [6] 25 sqr&#39;</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">&#39;[1] [8] [2] [7] [4 3] [6] 625 z-up&#39;</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">&#39;[1] [8] [2] [7] [4 3] [6] 625 z-up&#39;</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>
@ -169,13 +167,13 @@ but see below.</p>
<span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="o">.</span>
</pre></div>
</div>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[1] [8] [2] [7] [3 4 625 6] z-up&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[1] [8] [2] [7] [3 4 625 6] z-up&#39;</span><span class="p">)</span>
</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">&#39;[1] [8] [2 [3 4 625 6] 7] z-up&#39;</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">&#39;[1] [8] [2 [3 4 625 6] 7] z-up&#39;</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>
@ -186,7 +184,7 @@ but see below.</p>
<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">&#39;[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra&#39;</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">&#39;[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra&#39;</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>
@ -237,11 +235,11 @@ been embedded in a nested series of quoted programs, e.g.:</p>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">Z</span></code> function isnt hard to make.</p>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;Z == [[] cons cons] step i&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">&#39;Z == [[] cons cons] step i&#39;</span><span class="p">)</span>
</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">&#39;1 [2 3 4] Z&#39;</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">&#39;1 [2 3 4] Z&#39;</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>
@ -274,7 +272,7 @@ been embedded in a nested series of quoted programs, e.g.:</p>
</pre></div>
</div>
<p>And here it is doing the main thing.</p>
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z&#39;</span><span class="p">)</span>
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">&#39;[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z&#39;</span><span class="p">)</span>
</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>
@ -306,50 +304,22 @@ i d i d i d d Bingo!
</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">Newtons method</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
<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>
@ -361,24 +331,25 @@ i d i d i d d Bingo!
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/notebooks/Zipper.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -389,7 +360,7 @@ i d i d i d d Bingo!
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="essays-about-programming-in-joy">
@ -120,7 +119,7 @@
</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öials Rules</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html#part-i-poials-rules">Part I: Pöials 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>
@ -147,9 +146,9 @@
</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">Brzozowskis 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">Brzozowskis 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">Lets try it out…</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#lets-try-it-out">Lets 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>
@ -161,51 +160,10 @@
</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">Newtons method</a></li>
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
</ul>
</li>
</ul>
<div class="relations">
<div class="sphinxsidebarwrapper"><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../index.html">Documentation overview</a><ul>
@ -214,24 +172,25 @@
</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>
@ -242,7 +201,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="parsing-text-into-joy-expressions">
@ -52,36 +51,37 @@ literal value (integer, float, string, or Joy expression) or a function
symbol. Function symbols are unquoted strings and cannot contain square
brackets. Terms must be separated by blanks, which can be omitted
around square brackets.</p>
<dl class="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>
@ -93,37 +93,18 @@ Any unbalanced square brackets will raise a ParseError.</p>
</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>
@ -133,24 +114,25 @@ Any unbalanced square brackets will raise a ParseError.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/parser.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -161,7 +143,7 @@ Any unbalanced square brackets will raise a ParseError.</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="tracing-joy-execution">
@ -54,60 +53,71 @@ joy?
<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 TracePrinters history.
Pass this method as the <code class="docutils literal notranslate"><span class="pre">viewer</span></code> argument to the <a class="reference internal" href="joy.html#joy.joy.joy" title="joy.joy.joy"><code class="xref py py-func docutils literal notranslate"><span class="pre">joy.joy.joy()</span></code></a> function.</p>
<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>
@ -115,36 +125,17 @@ trace of the evaluation</p>
</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>
@ -154,24 +145,25 @@ trace of the evaluation</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/pretty.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -182,7 +174,7 @@ trace of the evaluation</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -30,8 +31,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
@ -90,34 +89,10 @@
</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>
@ -125,23 +100,17 @@
</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>
@ -152,7 +121,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,23 +1,27 @@
<!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 &#8212; 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" />
@ -32,24 +36,24 @@
<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>
@ -59,48 +63,16 @@
</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>
@ -111,7 +83,7 @@
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

File diff suppressed because one or more lines are too long

View File

@ -1,18 +1,19 @@
<!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… &#8212; 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" />
@ -29,8 +30,6 @@
<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">
@ -43,9 +42,9 @@ permits certain operations such as iterating and pushing and popping
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>
@ -81,119 +80,137 @@ iterable and another to iterate through a stack and yield its items
one-by-one in order. There are also two functions to generate string representations
of stacks. They only differ in that one prints the terms in stack from left-to-right while the other prints from right-to-left. In both functions <em>internal stacks</em> are
printed left-to-right. These functions are written to support <a class="reference internal" href="pretty.html"><span class="doc">Tracing Joy Execution</span></a>.</p>
<dl class="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">-&gt;</span> <span class="s1">&#39;top second ...&#39;</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">-&gt;</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">())))</span>
</pre></div>
</div>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>el</strong> (<em>list</em>) A Python list or other sequence (iterators and generators
wont work because <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> is called on <code class="docutils literal notranslate"><span class="pre">el</span></code>.)</p></li>
<li><p><strong>stack</strong> (<em>stack</em>) A stack, optional, defaults to the empty stack.</p></li>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
<li><strong>el</strong> (<em>list</em>) A Python list or other sequence (iterators and generators
wont work because <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> is called on <code class="docutils literal notranslate"><span class="pre">el</span></code>.)</li>
<li><strong>stack</strong> (<em>stack</em>) A stack, optional, defaults to the empty stack.</li>
</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">-&gt;</span> <span class="s1">&#39;... second top&#39;</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>
@ -201,36 +218,17 @@ wont work because <code class="docutils literal notranslate"><span class="pre
</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>
@ -240,24 +238,25 @@ wont work because <code class="docutils literal notranslate"><span class="pre
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/stack.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -268,7 +267,7 @@ wont work because <code class="docutils literal notranslate"><span class="pre
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,18 +1,19 @@
<!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 &#8212; 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" />
@ -29,8 +30,6 @@
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="type-inference-of-joy-expressions">
@ -108,37 +107,26 @@ auto-compiled to Python):</p>
<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.
@ -148,67 +136,44 @@ combinators themselves.</p>
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>
<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 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>
</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>
@ -218,118 +183,85 @@ guard against being used on invalid types.</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 dont 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>
<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">
<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>
</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>
<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>
</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>
@ -343,43 +275,43 @@ is used to generate one.</p>
</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 its indeterminate (because I havent 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>
@ -451,36 +383,17 @@ far.</p>
</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>
@ -490,24 +403,25 @@ far.</p>
</ul></li>
</ul>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/types.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 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>
@ -518,7 +432,7 @@ far.</p>
</a>
<br />
<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Thun Documentation</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://joypy.osdn.io/" property="cc:attributionName" rel="cc:attributionURL">Simon Forman</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.<br />Based on a work at <a xmlns:dct="http://purl.org/dc/terms/" href="https://osdn.net/projects/joypy/" rel="dct:source">https://osdn.net/projects/joypy/</a>.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 3.0.2.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.7.3.
</div>
</body>

View File

@ -1,69 +1,69 @@
∂RE
===
Brzozowski's Derivatives of Regular Expressions
Brzozowskis Derivatives of Regular Expressions
-----------------------------------------------
Legend:
::
∧ intersection
union
∘ concatenation (see below)
¬ complement
ϕ empty set (aka ∅)
λ singleton set containing just the empty string
I set of all letters in alphabet
∧ 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:
@ -71,7 +71,7 @@ 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
--------------
@ -94,11 +94,11 @@ The empty set and the set of just the empty string.
Two-letter Alphabet
~~~~~~~~~~~~~~~~~~~
I'm only going to use two symbols (at first) becaase this is enough to
Im only going to use two symbols (at first) becaase this is enough to
illustrate the algorithm and because you can represent any other
alphabet with two symbols (if you had to.)
I chose the names ``O`` and ``l`` (uppercase "o" and lowercase "L") to
I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
look like ``0`` and ``1`` (zero and one) respectively.
.. code:: ipython2
@ -108,18 +108,18 @@ look like ``0`` and ``1`` (zero and one) respectively.
Representing Regular Expressions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To represent REs in Python I'm going to use tagged tuples. A *regular
To represent REs in Python Im going to use tagged tuples. A *regular
expression* is one of:
::
O
l
(KSTAR, R)
(NOT, R)
(AND, R, S)
(CONS, R, S)
(OR, R, S)
O
l
(KSTAR, R)
(NOT, R)
(AND, R, S)
(CONS, R, S)
(OR, R, S)
Where ``R`` and ``S`` stand for *regular expressions*.
@ -169,11 +169,11 @@ String Representation of RE Datastructures
``I``
~~~~~
Match anything. Often spelled "."
Match anything. Often spelled “.”
::
I = (0|1)*
I = (0|1)*
.. code:: ipython2
@ -196,8 +196,8 @@ The example expression from Brzozowski:
::
(.111.) & (.01 + 11*)'
a & (b + c)'
(.111.) & (.01 + 11*)'
a & (b + c)'
Note that it contains one of everything.
@ -221,7 +221,7 @@ Note that it contains one of everything.
``nully()``
~~~~~~~~~~~
Let's get that auxiliary predicate function ``δ`` out of the way.
Lets get that auxiliary predicate function ``δ`` out of the way.
.. code:: ipython2
@ -256,10 +256,10 @@ Let's get that auxiliary predicate function ``δ`` out of the way.
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.
@ -359,7 +359,7 @@ are *pure* so this is fine.
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
@ -409,8 +409,8 @@ expressions from growing too large.
return derv
Let's try it out...
-------------------
Lets try it out…
-----------------
(FIXME: redo.)
@ -460,27 +460,27 @@ Should match:
::
(.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 youll see that we never use the “set-ness” of the symbols ``O``
and ``l``. The only time Python set operators (``&`` and ``|``) appear
is in the ``nully()`` function, and there they operate on (recursively
computed) outputs of that function, never ``O`` and ``l``.
@ -489,33 +489,33 @@ What if we try:
::
(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
@ -529,9 +529,9 @@ machine transition table.
::
.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 1s and not ending in 01 nor composed of all 1s.”
.. figure:: attachment:omg.svg
:alt: omg.svg
@ -540,32 +540,32 @@ Says, "Three or more 1's and not ending in 01 nor composed of all 1's."
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/>`__.) Youll see that only
paths that lead to one of the accepting states will match the regular
expression. All other paths will terminate at one of the non-accepting
states.
There's a happy path to ``g`` along 111:
Theres 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`` youre stuck there eating 1s until you see a 0,
which takes you to the ``i→j→i|i→j→h→i`` “trap”. You cant reach any
other states from those two loops.
If you see a 0 before you see 111 you will reach ``b``, which forms
another "trap" with ``d`` and ``f``. The only way out is another happy
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 1s or as many 0 in a
row and still be either still at ``h`` (for 1s) or move to ``i`` (for
0s). If you find yourself at ``i`` you can see as many 0s, or
repetitions of 10, as there are, but if you see just a 1 you move to
``j``.
@ -575,14 +575,14 @@ RE to FSM
So how do we get the state machine from the regular expression?
It turns out that each RE is effectively a state, and each arrow points
to the derivative RE in respect to the arrow's symbol.
to the derivative RE in respect to the arrows symbol.
If we label the initial RE ``a``, we can say:
::
a --0--> ∂0(a)
a --1--> ∂1(a)
a --0--> ∂0(a)
a --1--> ∂1(a)
And so on, each new unique RE is a new state in the FSM table.
@ -590,18 +590,18 @@ Here are the derived REs at each state:
::
a = (.111.) & ((.01 | 11*)')
b = (.111.) & ((.01 | 1)')
c = (.111. | 11.) & ((.01 | 1*)')
d = (.111. | 11.) & ((.01 | ^)')
e = (.111. | 11. | 1.) & ((.01 | 1*)')
f = (.111. | 11. | 1.) & ((.01)')
g = (.01 | 1*)'
h = (.01)'
i = (.01 | 1)'
j = (.01 | ^)'
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"
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.
@ -764,16 +764,16 @@ Drive a FSM
There are *lots* of FSM libraries already. Once you have the state
transition table they should all be straightforward to use. State
Machine code is very simple. Just for fun, here is an implementation in
Python that imitates what "compiled" FSM code might look like in an
"unrolled" form. Most FSM code uses a little driver loop and a table
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
@ -790,8 +790,8 @@ function.
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
@ -831,7 +831,7 @@ labels.)
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`` isnt.
.. code:: ipython2
@ -885,7 +885,7 @@ Reversing the Derivatives to Generate Matching Strings
------------------------------------------------------
(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
@ -893,54 +893,54 @@ derivative-with-respect-to-N of some other state/RE:
::
c = d1(a)
b = d0(a)
b = d0(c)
...
i = d0(j)
j = d1(i)
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)*

View File

@ -11,51 +11,51 @@ Consider the ``x`` combinator:
::
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:
Lets try it:
.. code:: ipython2
@ -128,32 +128,32 @@ our quoted program:
::
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:
Lets try it out:
.. code:: ipython2
@ -208,20 +208,20 @@ Generating Multiples of Three and Five
--------------------------------------
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 youll 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.
@ -250,7 +250,7 @@ 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
@ -262,8 +262,7 @@ If we plug ``14811`` and ``[PE1.1]`` into our generator form...
[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
@ -306,15 +305,15 @@ if so.
(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
thats a little beyond the scope of this article. This solution does
extra work, but not much, and were not using it “in production” as they
say.)
Run 466 times
~~~~~~~~~~~~~
In the PE1 problem we are asked to sum all the multiples of three and
five less than 1000. It's worked out that we need to use all seven
five less than 1000. Its worked out that we need to use all seven
numbers sixty-six times and then four more.
.. code:: ipython2
@ -375,76 +374,76 @@ Consider:
::
[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``:
Lets 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
@ -467,8 +466,8 @@ Putting it all together:
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
@ -479,13 +478,13 @@ 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 its straightforward to define ``PE2`` as a recursive function that
generates terms in the Fibonacci sequence until they exceed four million
and sums the even ones.
@ -503,18 +502,18 @@ and sums the even ones.
4613732
Here's the collected program definitions:
Heres 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
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -523,16 +522,16 @@ Using ``o`` for odd and ``e`` for even:
::
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.

View File

@ -22,8 +22,8 @@ that you start by running the package:
::
$ 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.
@ -31,7 +31,7 @@ that you start by running the package:
docs for a word.
<-top
<-top
joy? _
@ -40,7 +40,14 @@ You can enter Joy notation at the prompt and a :doc:`trace of evaluation <../pre
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 +

View File

@ -1,10 +1,10 @@
`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
`Newtons method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
=====================================================================
Let's use the Newton-Raphson method for finding the root of an equation
Lets use the Newton-Raphson method for finding the root of an equation
to write a function that can compute the square root of a number.
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
@ -20,9 +20,9 @@ computes the next approximation:
::
a F
---------
a'
a F
---------
a'
A Function to Compute the Next Approximation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -34,17 +34,17 @@ square root:
::
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
~~~~~~~~~~~~~~~~~~~~~~~~
@ -53,27 +53,27 @@ Our generator would be created by:
::
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 were writing. If we let 1 be the initial approximation:
::
1 n 1 / + 2 /
1 n/1 + 2 /
1 n + 2 /
n+1 2 /
(n+1)/2
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
@ -89,8 +89,8 @@ The generator can be written as:
[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...
Lets drive the generator a few time (with the ``x`` combinator) and
square the approximation to see how well it works
.. code:: ipython2
@ -105,42 +105,42 @@ square the approximation to see how well it works...
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
@ -151,10 +151,10 @@ Base-Case
::
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
@ -165,7 +165,7 @@ Recur
::
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``.
@ -175,14 +175,14 @@ Pretty straightforward:
::
a [b G] ε R0 [within] R1
a [b G] ε [popd x] dip [within] i
a [b G] popd x ε [within] i
[b G] x ε [within] i
b [c G] ε [within] i
b [c G] ε within
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
@ -196,15 +196,15 @@ The recursive function we have defined so far needs a slight preamble:
::
[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

File diff suppressed because it is too large Load Diff

View File

@ -10,9 +10,9 @@ Cf.
::
-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}`
@ -28,21 +28,21 @@ a definition without them.
::
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 * /
``±``
~~~~~
@ -52,14 +52,14 @@ replaces them with their sum and difference.
::
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``.
@ -72,20 +72,20 @@ the variables:
::
b neg b sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
b [neg] dupdip sqr 4 a c * * - sqrt pm a 2 * [/] cons app2
b a c [[neg] dupdip sqr 4] dipd * * - sqrt pm a 2 * [/] cons app2
b a c a [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
b a c over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2
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 its 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:
Lets try it out:
.. code:: ipython2

View File

@ -10,44 +10,43 @@ several generic specializations.
::
[if] [then] [rec1] [rec2] genrec
---------------------------------------------------------------------
[if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
[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:
From “Recursion Theory and Joy” (j05cmp.html) by Manfred von Thun:
"The genrec combinator takes four program parameters in addition to
whatever data parameters it needs. Fourth from the top is an
if-part, followed by a then-part. If the if-part yields true, then
the then-part is executed and the combinator terminates. The other
two parameters are the rec1-part and the rec2-part. If the if-part
yields false, the rec1-part is executed. Following that the four
program parameters and the combinator are again pushed onto the
stack bundled up in a quoted form. Then the rec2-part is executed,
where it will find the bundled form. Typically it will then execute
the bundled form, either with i or with app2, or some other
combinator."
“The 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.
@ -59,9 +58,9 @@ Primitive recursive functions are those where ``R2 == i``.
::
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>`__
------------------------------------------------------------------------------------
@ -75,8 +74,8 @@ is a recursive function ``H :: A -> C`` that converts a value of type
- 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.
@ -96,12 +95,12 @@ 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
-------------------
@ -111,7 +110,7 @@ hylomorphism combinator ``H`` from constituent parts.
::
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
@ -120,37 +119,37 @@ with the base case value ``c``.)
::
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
-----------------------------------------
@ -160,9 +159,9 @@ arguments out of the pieces given to the ``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:
@ -174,17 +173,17 @@ So:
::
H == [P] [pop c] [G] [dip F] genrec
[P] [c] [pop] swoncat [G] [F] [dip] swoncat genrec
[P] c unit [pop] swoncat [G] [F] [dip] swoncat genrec
[P] c [G] [F] [unit [pop] swoncat] dipd [dip] swoncat genrec
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
@ -193,7 +192,7 @@ the left so we have a definition for ``hylomorphism``:
Example: Finding `Triangular Numbers <https://en.wikipedia.org/wiki/Triangular_number>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let's write a function that, given a positive integer, returns the sum
Lets write a function that, given a positive integer, returns the sum
of all positive integers less than that one. (In this case the types
``A``, ``B`` and ``C`` are all ``int``.)
@ -208,7 +207,7 @@ To sum a range of integers from 0 to *n* - 1:
define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')
Let's try it:
Lets try it:
.. code:: ipython2
@ -236,30 +235,30 @@ Four Specializations
There are at least four kinds of recursive combinator, depending on two
choices. The first choice is whether the combiner function ``F`` should
be evaluated during the recursion or pushed into the pending expression
to be "collapsed" at the end. The second choice is whether the combiner
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
generators output, in other words, whether ``F`` or ``G`` should run
first in the recursive branch.
::
H1 == [P] [pop c] [G ] [dip F] genrec
H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
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.
@ -269,31 +268,31 @@ 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``
@ -307,53 +306,53 @@ reverse order.
::
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 youll see that the combiner ``F`` only
gets to operate on the results of ``G``, it never “sees” the first value
``a``. If the combiner and the generator both need to work on the
current value then ``dup`` must be used, and the generator must produce
one item instead of two (the b is instead the duplicate of a.)
::
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
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``
~~~~~~
@ -364,22 +363,22 @@ the form:
::
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
-----------
@ -390,13 +389,10 @@ values.
::
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.
@ -406,8 +402,8 @@ Each of the above variations can be used to make four slightly different
::
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
@ -428,8 +424,8 @@ Each of the above variations can be used to make four slightly different
::
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
@ -450,8 +446,8 @@ Each of the above variations can be used to make four slightly different
::
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
@ -472,8 +468,8 @@ Each of the above variations can be used to make four slightly different
::
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
@ -503,7 +499,7 @@ and makes some new value.
::
C == [not] c [uncons swap] [F] hylomorphism
C == [not] c [uncons swap] [F] hylomorphism
.. code:: ipython2
@ -513,7 +509,7 @@ An example of a catamorphism is the sum function.
::
sum == [not] 0 [swuncons] [+] hylomorphism
sum == [not] 0 [swuncons] [+] hylomorphism
.. code:: ipython2
@ -585,16 +581,16 @@ For the Factorial function:
::
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
@ -613,31 +609,31 @@ With:
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
@ -656,39 +652,39 @@ We would use:
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.”

View File

@ -4,8 +4,8 @@ Replacing Functions in the Dictionary
For now, there is no way to define new functions from within the Joy
language. All functions (and the interpreter) all accept and return a
dictionary parameter (in addition to the stack and expression) so that
we can implement e.g. a function that adds new functions to the
dictionary. However, 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, theres no function that does that. Adding a new
function to the dictionary is a meta-interpreter action, you have to do
it in Python, not Joy.
@ -74,8 +74,8 @@ Both ``sum`` and ``size`` each convert a sequence to a single value.
::
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

View File

@ -17,10 +17,10 @@ symbols together, juxtaposition:
::
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
------
@ -29,72 +29,72 @@ Do one thing or another.
::
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 doesnt *have*
to be Boolean because Pythons rules for “truthiness” will be used to
evaluate it. I reflect this in the structure of the stack effect comment
of ``branch``, it will only accept Boolean values, and in the definition
of ``ifte`` above by including ``not`` in the quote, which also has the
@ -107,17 +107,17 @@ Do one thing zero or more times.
::
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
@ -128,21 +128,21 @@ constructs that do not need to be directly self-referential, unlike
::
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
@ -150,15 +150,15 @@ boolean flag for the next iteration:
::
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``
~~~~~~~~~
@ -170,21 +170,21 @@ flag for the next iteration:
::
[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
--------
@ -192,11 +192,11 @@ 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 couldnt be
reimplemented in terms of e.g. Python threads. I am not concerned with
performance of the system just yet, only the elegance of the code it
allows us to write.
@ -207,27 +207,27 @@ Joy has a few parallel combinators, the main one being ``cleave``:
::
... x [A] [B] cleave
---------------------------------------------------------
... [x ...] [A] infra first [x ...] [B] infra first
---------------------------------------------------------
... a b
... 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.)
Elliotts “Compiling to Categories” paper, et. al.)
Just a thought, if you ``cleave`` two jobs and one requires more time to
finish than the other you'd like to be able to assign resources
finish than the other youd 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
@ -235,35 +235,35 @@ than one value:
::
... 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
(Im not sure why ``cleave`` was specified to take that value, I may
make a combinator that does the same thing but without expecting a
value.)
::
clv == [i] app2
clv == [i] app2
[A] [B] clv
------------------
a b
[A] [B] clv
------------------
a b
``map``
~~~~~~~
@ -273,10 +273,10 @@ The common ``map`` function in Joy should also be though of as a
::
[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`` couldnt distribute
the ``Q`` function over e.g. a pool of worker CPUs.
``pam``
~~~~~~~
@ -285,16 +285,16 @@ One of my favorite combinators, the ``pam`` combinator is just:
::
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -302,7 +302,7 @@ 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
^^^^^^^^^^^^^^^
@ -313,24 +313,24 @@ stack could be replaced by its output stack.
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 Im not going to worry about
it. (And I think the Categories can deal with it anyhow? Incremental
evaluation, yeah?)

View File

@ -1,8 +1,8 @@
Treating Trees II: ``treestep``
===============================
Let's consider a tree structure, similar to one described `"Why
functional programming matters" by John
Lets consider a tree structure, similar to one described `“Why
functional programming matters by John
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__,
that consists of a node value followed by zero or more child trees. (The
asterisk is meant to indicate the `Kleene
@ -10,7 +10,7 @@ star <https://en.wikipedia.org/wiki/Kleene_star>`__.)
::
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
@ -18,15 +18,15 @@ base-case function ``[B]``, and two quoted programs ``[N]`` and ``[C]``.
::
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
@ -34,11 +34,11 @@ combine the result with ``C``.
::
[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 well experiment with making ``map`` part of ``C`` so you can
use other combinators.)
Derive the recursive function.
@ -49,59 +49,59 @@ will produce.
::
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``.
Lets 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.
-----------------------------------------------
@ -110,26 +110,26 @@ Working backwards:
::
[not] [B] [uncons [N] dip] [map C] genrec
[B] [not] swap [uncons [N] dip] [map C] genrec
[B] [uncons [N] dip] [[not] swap] dip [map C] genrec
^^^^^^^^^^^^^^^^
[B] [[N] dip] [uncons] swoncat [[not] swap] dip [map C] genrec
[B] [N] [dip] cons [uncons] swoncat [[not] swap] dip [map C] genrec
^^^^^^^^^^^^^^^^^^^^^^^^^^^
[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.
@ -140,10 +140,10 @@ Working backwards:
::
[not] [B] [uncons [N] dip] [map C] genrec
[not] [B] [N] [dip] cons [uncons] swoncat [map C] genrec
[B] [N] [not] roll> [dip] cons [uncons] swoncat [map C] genrec
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[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``
-------------------
@ -171,7 +171,7 @@ all nodes in a tree with this function:
::
sumtree == [pop 0] [] [sum +] treestep
sumtree == [pop 0] [] [sum +] treestep
.. code:: ipython2
@ -181,9 +181,9 @@ Running this function on an empty tree value gives zero:
::
[] [pop 0] [] [sum +] treestep
------------------------------------
0
[] [pop 0] [] [sum +] treestep
------------------------------------
0
.. code:: ipython2
@ -199,11 +199,11 @@ Running it on a non-empty node:
::
[n tree*] [pop 0] [] [sum +] treestep
n [tree*] [[pop 0] [] [sum +] treestep] map sum +
n [ ... ] sum +
n m +
n+m
[n tree*] [pop 0] [] [sum +] treestep
n [tree*] [[pop 0] [] [sum +] treestep] map sum +
n [ ... ] sum +
n m +
n+m
.. code:: ipython2
@ -310,7 +310,7 @@ Redefining the Ordered Binary Tree in terms of ``treestep``.
::
Tree = [] | [[key value] left right]
Tree = [] | [[key value] left right]
What kind of functions can we write for this with our ``treestep``?
@ -318,26 +318,26 @@ 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
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 doesnt quite work:
.. code:: ipython2
@ -349,25 +349,25 @@ This doesn't quite work:
3 'B' 'B'
Doesn't work because ``map`` extracts the ``first`` item of whatever its
Doesnt work because ``map`` extracts the ``first`` item of whatever its
mapped function produces. We have to return a list, rather than
depositing our results directly on the stack.
::
[key value] N [left right] [K] map C
[key value] 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
@ -388,18 +388,18 @@ From here:
::
key [[lk] [rk]] C
key [[lk] [rk]] i
key [lk] [rk] roll<
[lk] [rk] key swons concat
[lk] [key rk] concat
[lk key rk]
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
@ -414,20 +414,20 @@ So:
With ``treegrind``?
-------------------
The ``treegrind`` function doesn't include the ``map`` combinator, so
The ``treegrind`` function doesnt include the ``map`` combinator, so
the ``[C]`` function must arrange to use some combinator on the quoted
recursive copy ``[K]``. With this function, the pattern for processing a
non-empty node is:
::
node N [tree*] [K] C
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
@ -454,7 +454,7 @@ Iteration through the nodes
[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
@ -485,28 +485,28 @@ I think we do:
::
[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
Well start by saying that the base-case (the key is not in the tree) is
user defined, and the per-node function is just the query key literal:
::
[B] [query_key] [C] treegrind
[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``:
Lets 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``
~~~~~~~~~~~~~~~~~~~
@ -516,16 +516,16 @@ equal):
::
[key value] query_key [left right] [K] P
[key value] query_key [left right] [K] roll<
[key value] [left right] [K] query_key [roll< uncons swap] dip
[key value] 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>``.)
@ -533,15 +533,15 @@ So now:
::
[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``
~~~~~
@ -550,27 +550,27 @@ Easy.
::
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.

View File

@ -98,7 +98,7 @@ An Example
(... [3 4 ] 2 1 0 -- ... [1 2 ])
Unification Works "in Reverse"
Unification Works “in Reverse”
------------------------------
.. code:: ipython2

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
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
@ -17,10 +17,9 @@ it, and rebuild it using the "zipper" technique.
Trees
-----
In Joypy there aren't any complex datastructures, just ints, floats,
In Joypy there arent any complex datastructures, just ints, floats,
strings, Symbols (strings that are names of functions) and sequences
(aka lists, aka quoted literals, aka aggregates, etc...), but we can
build
(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.
@ -45,12 +44,12 @@ In Joy we can do this with the following words:
::
z-down == [] swap uncons swap
z-up == swons swap shunt
z-right == [swons] cons dip uncons swap
z-left == swons [uncons swap] dip swap
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
Lets use them to change 25 into 625. The first time a word is used I
show the trace so you can see how it works. If we were going to use
these a lot it would make sense to write Python versions for efficiency,
but see below.
@ -208,8 +207,8 @@ 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
@ -247,8 +246,8 @@ or "address" any particular item in a Joy tree structure.
[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 youll see that about half of it is the
``dip`` and ``infra`` combinators de-quoting programs and “digging” into
the subject datastructure. Instead of maintaining temporary results on
the stack they are pushed into the pending expression (continuation).
When ``sqr`` has run the rest of the pending expression rebuilds the
@ -264,12 +263,12 @@ been embedded in a nested series of quoted programs, e.g.:
::
[...] [Q] [dip dip infra dip infra dip infra] Z
-------------------------------------------------------------
[...] [[[[[[[Q] dip] dip] infra] dip] infra] dip] infra
[...] [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 isnt hard to make.
.. code:: ipython2
@ -333,21 +332,21 @@ a string made from only two characters.
::
[...] [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"
Its easy to read off (in reverse) the right sequence of “d” and “i”
from the subject datastructure:
::
[ n [ n [ n n x ...
i d i d i d d Bingo!
[ n [ n [ n n x ...
i d i d i d d Bingo!

View File

@ -20,8 +20,8 @@ Symbolic Evaluation with SymPy
-------------------------------------------------------------------------------------------
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:
@ -34,12 +34,12 @@ If we evaluate the ``quadratic`` program
::
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 doesnt work with the SymPy
objects:
.. code:: ipython2
@ -96,8 +96,8 @@ We can pick out that first symbolic expression obect from the Joy stack:
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 “cant convert expression
to float exception but ``sympy.sqrt()`` does not:
.. code:: ipython2
@ -155,10 +155,10 @@ Now it works just fine.
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. Theres a
huge amount of incredibly useful stuff and I dont see why Joy shouldnt
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.)
@ -200,39 +200,39 @@ Translate ``F(u, k)`` to Joy
::
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?
Whats 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
@ -266,7 +266,7 @@ Try it out:
32
In order to elide the tests let's define special versions of ``while``
In order to elide the tests lets define special versions of ``while``
and ``ifte``:
.. code:: ipython2
@ -411,7 +411,7 @@ And with a SymPy symbol for the ``u`` argument:
Let's try partial evaluation by hand and use a "stronger" thunk.
Lets 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
@ -419,136 +419,136 @@ available and in the meantime treat the pending computation as one unit.
::
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
@ -581,7 +581,7 @@ To arrive at a startlingly elegant form for F5:
I'm not sure how to implement these kinds of thunks. I think you have to
Im 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.
@ -589,27 +589,27 @@ Working on the compiler, from this:
::
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
@ -658,13 +658,13 @@ In Joy:
::
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
@ -692,23 +692,23 @@ Original
::
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
@ -737,12 +737,12 @@ curried, quoted
::
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
@ -781,34 +781,34 @@ curried, quoted
::
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
@ -861,13 +861,13 @@ From this:
::
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()``:
--------------------
@ -966,7 +966,7 @@ Try it with ``F()``:
print source
eval(source)(2)
Hmm...
Hmm
.. code:: ipython2
@ -1062,81 +1062,81 @@ Hmm...
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 doesnt 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.

View File

@ -376,7 +376,7 @@ class DefinitionWrapper(object):
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):