Rebuild docs
This commit is contained in:
parent
ef6411205d
commit
56da4690d0
|
|
@ -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. There’s 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.
|
||||
That’s 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, there’s no function to add new definitions to the dictionary
|
||||
from “within” Joy code itself. Adding new definitions remains a
|
||||
meta-interpreter action. You have to do it yourself, in Python, and wash
|
||||
your hands afterward.
|
||||
|
||||
It would be simple enough to define one, but it would open the door to
|
||||
*name binding* and break the idea that all state is captured in the
|
||||
stack and expression. There's an implicit *standard dictionary* that
|
||||
stack and expression. There’s an implicit *standard dictionary* that
|
||||
defines the actual semantics of the syntactic stack and expression
|
||||
datastructures (which only contain symbols, not the actual functions.
|
||||
Pickle some and see for yourself.)
|
||||
|
||||
"There should be only one."
|
||||
“There should be only one.”
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Which brings me to talking about one of my hopes and dreams for this
|
||||
notation: "There should be only one." What I mean is that there should
|
||||
notation: “There should be only one.” What I mean is that there should
|
||||
be one universal standard dictionary of commands, and all bespoke work
|
||||
done in a UI for purposes takes place by direct interaction and macros.
|
||||
There would be a *Grand Refactoring* biannually (two years, not six
|
||||
months, that's semi-annually) where any new definitions factored out of
|
||||
months, that’s semi-annually) where any new definitions factored out of
|
||||
the usage and macros of the previous time, along with new algorithms and
|
||||
such, were entered into the dictionary and posted to e.g. IPFS.
|
||||
such, were entered into the dictionary and posted to e.g. IPFS.
|
||||
|
||||
Code should not burgeon wildly, as it does today. The variety of code
|
||||
should map more-or-less to the well-factored variety of human
|
||||
computably-solvable problems. There shouldn't be dozens of chat apps, JS
|
||||
frameworks, programming languages. It's a waste of time, a `fractal
|
||||
"thundering herd"
|
||||
computably-solvable problems. There shouldn’t be dozens of chat apps, JS
|
||||
frameworks, programming languages. It’s a waste of time, a `fractal
|
||||
“thundering herd”
|
||||
attack <https://en.wikipedia.org/wiki/Thundering_herd_problem>`__ on
|
||||
human mentality.
|
||||
|
||||
Literary Code Library
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you read over the other notebooks you'll see that developing code in
|
||||
If you read over the other notebooks you’ll see that developing code in
|
||||
Joy is a lot like doing simple mathematics, and the descriptions of the
|
||||
code resemble math papers. The code also works the first time, no bugs.
|
||||
If you have any experience programming at all, you are probably
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
Here’s a longer trace.
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
|
|||
|
|
@ -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.)
|
||||
it’s “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.)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Let’s 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. It’s
|
||||
good but there’s one more trick we can apply. The list of seven terms
|
||||
takes up at least seven bytes. But notice that all of the terms are less
|
||||
than four, and so each can fit in just two bits. We could store all
|
||||
seven terms in just fourteen bits and use masking and shifts to pick out
|
||||
|
|
@ -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.
|
||||
Let’s refactor.
|
||||
|
||||
::
|
||||
|
||||
14811 7 [PE1.2] times pop
|
||||
14811 4 [PE1.2] times pop
|
||||
14811 n [PE1.2] times pop
|
||||
n 14811 swap [PE1.2] times pop
|
||||
14811 7 [PE1.2] times pop
|
||||
14811 4 [PE1.2] times pop
|
||||
14811 n [PE1.2] times pop
|
||||
n 14811 swap [PE1.2] times pop
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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,
|
||||
Here’s our joy program all in one place. It doesn’t make so much sense,
|
||||
but if you have read through the above description of how it was derived
|
||||
I hope it's clear.
|
||||
I hope it’s clear.
|
||||
|
||||
::
|
||||
|
||||
PE1.1 == + [+] dupdip
|
||||
PE1.2 == [3 & PE1.1] dupdip 2 >>
|
||||
PE1.3 == 14811 swap [PE1.2] times pop
|
||||
PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop
|
||||
PE1.1 == + [+] dupdip
|
||||
PE1.2 == [3 & PE1.1] dupdip 2 >>
|
||||
PE1.3 == 14811 swap [PE1.2] times pop
|
||||
PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop
|
||||
|
||||
Generator Version
|
||||
=================
|
||||
|
||||
It's a little clunky iterating sixty-six times though the seven numbers
|
||||
It’s a little clunky iterating sixty-six times though the seven numbers
|
||||
then four more. In the *Generator Programs* notebook we derive a
|
||||
generator that can be repeatedly driven by the ``x`` combinator to
|
||||
produce a stream of the seven numbers repeating over and over again.
|
||||
|
|
@ -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 we’re 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, I’ll 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
|
||||
It’s worth noting, I think, that this same reasoning holds for any two
|
||||
numbers :math:`n` and :math:`m` the multiples of which we hope to sum.
|
||||
The multiples would have a cycle of differences of length :math:`k` and
|
||||
so we could compute the sum of :math:`Nk` multiples as above.
|
||||
|
|
@ -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* don’t matter, the pattern they make will always be symmetrical
|
||||
around its midpoint. The same reasoning holds for multiples of more than
|
||||
two numbers.
|
||||
|
||||
|
|
@ -793,6 +793,6 @@ is just:
|
|||
|
||||
::
|
||||
|
||||
PE1 == 233168
|
||||
PE1 == 233168
|
||||
|
||||
Fin.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
I’ll assume the input is a Joy sequence of integers (as opposed to a
|
||||
string or something else.)
|
||||
|
||||
We might proceed by creating a word that makes a copy of the sequence
|
||||
|
|
@ -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``:
|
||||
Let’s derive ``pair_up``:
|
||||
|
||||
::
|
||||
|
||||
[a b c] pair_up
|
||||
-------------------------
|
||||
[[a b] [b c] [c a]]
|
||||
[a b c] pair_up
|
||||
-------------------------
|
||||
[[a b] [b c] [c a]]
|
||||
|
||||
Straightforward (although the order of each pair is reversed, due to the
|
||||
way ``zip`` works, but it doesn't matter for this program):
|
||||
way ``zip`` works, but it doesn’t matter for this program):
|
||||
|
||||
::
|
||||
|
||||
[a b c] dup
|
||||
[a b c] [a b c] uncons swap
|
||||
[a b c] [b c] a unit concat
|
||||
[a b c] [b c a] zip
|
||||
[[b a] [c b] [a c]]
|
||||
[a b c] dup
|
||||
[a b c] [a b c] uncons swap
|
||||
[a b c] [b c] a unit concat
|
||||
[a b c] [b c a] zip
|
||||
[[b a] [c b] [a c]]
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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 row’s largest and smallest values are 9 and 1, and their
|
||||
difference is 8.
|
||||
- The second row's largest and smallest values are 7 and 3, and their
|
||||
- The second row’s largest and smallest values are 7 and 3, and their
|
||||
difference is 4.
|
||||
- The third row's difference is 6.
|
||||
- The third row’s difference is 6.
|
||||
|
||||
In this example, the spreadsheet's checksum would be 8 + 4 + 6 = 18.
|
||||
In this example, the spreadsheet’s checksum would be 8 + 4 + 6 = 18.
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
from notebook_preamble import J, V, define
|
||||
|
||||
I'll assume the input is a Joy sequence of sequences of integers.
|
||||
I’ll assume the input is a Joy sequence of sequences of integers.
|
||||
|
||||
::
|
||||
|
||||
[[5 1 9 5]
|
||||
[7 5 3]
|
||||
[2 4 6 8]]
|
||||
[[5 1 9 5]
|
||||
[7 5 3]
|
||||
[2 4 6 8]]
|
||||
|
||||
So, obviously, the initial form will be a ``step`` function:
|
||||
|
||||
::
|
||||
|
||||
AoC2017.2 == 0 swap [F +] step
|
||||
AoC2017.2 == 0 swap [F +] step
|
||||
|
||||
This function ``F`` must get the ``max`` and ``min`` of a row of numbers
|
||||
and subtract. We can define a helper function ``maxmin`` which does
|
||||
|
|
@ -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 line’s result.
|
||||
|
||||
For example, given the following spreadsheet:
|
||||
|
||||
::
|
||||
|
||||
5 9 2 8
|
||||
9 4 7 3
|
||||
3 8 6 5
|
||||
5 9 2 8
|
||||
9 4 7 3
|
||||
3 8 6 5
|
||||
|
||||
- In the first row, the only two numbers that evenly divide are 8 and
|
||||
2; the result of this division is 4.
|
||||
|
|
@ -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 row’s 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.
|
||||
Let’s think.
|
||||
|
||||
Given a *sorted* sequence (from highest to lowest) we want to \* for
|
||||
head, tail in sequence \* for term in tail: \* check if the head % term
|
||||
|
|
@ -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 don’t need it.
|
||||
|
||||
::
|
||||
|
||||
[b c d] [b c d] a [P] [T] [cons] app2 popdd [E] primrec
|
||||
[b c d] [b c d] [a P] [a T] [E] primrec
|
||||
[b c d] [b c d] a [P] [T] [cons] app2 popdd [E] primrec
|
||||
[b c d] [b c d] [a P] [a T] [E] primrec
|
||||
|
||||
--------------
|
||||
|
||||
::
|
||||
|
||||
w/ Q == [% not] [T] [F] primrec
|
||||
w/ Q == [% not] [T] [F] primrec
|
||||
|
||||
[a b c d] uncons
|
||||
a [b c d] tuck
|
||||
[b c d] a [b c d] uncons
|
||||
[b c d] a b [c d] roll>
|
||||
[b c d] [c d] a b Q
|
||||
[b c d] [c d] a b [% not] [T] [F] primrec
|
||||
[a b c d] uncons
|
||||
a [b c d] tuck
|
||||
[b c d] a [b c d] uncons
|
||||
[b c d] a b [c d] roll>
|
||||
[b c d] [c d] a b Q
|
||||
[b c d] [c d] a b [% not] [T] [F] primrec
|
||||
|
||||
[b c d] [c d] a b T
|
||||
[b c d] [c d] a b / roll> popop 0
|
||||
[b c d] [c d] a b T
|
||||
[b c d] [c d] a b / roll> popop 0
|
||||
|
||||
[b c d] [c d] a b F Q
|
||||
[b c d] [c d] a b pop swap uncons ... Q
|
||||
[b c d] [c d] a swap uncons ... Q
|
||||
[b c d] a [c d] uncons ... Q
|
||||
[b c d] a c [d] roll> Q
|
||||
[b c d] [d] a c Q
|
||||
[b c d] [c d] a b F Q
|
||||
[b c d] [c d] a b pop swap uncons ... Q
|
||||
[b c d] [c d] a swap uncons ... Q
|
||||
[b c d] a [c d] uncons ... Q
|
||||
[b c d] a c [d] roll> Q
|
||||
[b c d] [d] a c Q
|
||||
|
||||
Q == [% not] [/ roll> popop 0] [pop swap uncons roll>] primrec
|
||||
Q == [% not] [/ roll> popop 0] [pop swap uncons roll>] primrec
|
||||
|
||||
uncons tuck uncons roll> Q
|
||||
uncons tuck uncons roll> Q
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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
|
||||
It’s a recursive function that conditionally executes the recursive part
|
||||
of its recursive branch
|
||||
|
||||
::
|
||||
|
||||
[Pg] [E] [R1 [Pi] [T]] [ifte] genrec
|
||||
[Pg] [E] [R1 [Pi] [T]] [ifte] genrec
|
||||
|
||||
The recursive branch is the else-part of the inner ``ifte``:
|
||||
|
||||
::
|
||||
|
||||
G == [Pg] [E] [R1 [Pi] [T]] [ifte] genrec
|
||||
== [Pg] [E] [R1 [Pi] [T] [G] ifte] ifte
|
||||
G == [Pg] [E] [R1 [Pi] [T]] [ifte] genrec
|
||||
== [Pg] [E] [R1 [Pi] [T] [G] ifte] ifte
|
||||
|
||||
But this is in hindsight. Going forward I derived:
|
||||
|
||||
::
|
||||
|
||||
G == [first % not]
|
||||
[first /]
|
||||
[rest [not] [popop 0]]
|
||||
[ifte] genrec
|
||||
G == [first % not]
|
||||
[first /]
|
||||
[rest [not] [popop 0]]
|
||||
[ifte] genrec
|
||||
|
||||
The predicate detects if the ``n`` can be evenly divided by the
|
||||
``first`` item in the list. If so, the then-part returns the result.
|
||||
|
|
@ -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. It’s going to be designed
|
||||
to work on a stack that has some candidate ``n``, a sequence of possible
|
||||
divisors, and a result that is zero to signal to continue (a non-zero
|
||||
value implies that it is the discovered result):
|
||||
|
||||
::
|
||||
|
||||
n [...] p find-result
|
||||
---------------------------
|
||||
result
|
||||
n [...] p find-result
|
||||
---------------------------
|
||||
result
|
||||
|
||||
It applies ``G`` using ``nullary`` because if it fails with one
|
||||
candidate it needs the list to get the next one (the list is otherwise
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 it’s at the access port.
|
||||
- Data from square 12 is carried 3 steps, such as: down, left, left.
|
||||
- Data from square 23 is carried only 2 steps: up twice.
|
||||
- Data from square 1024 must be carried 31 steps.
|
||||
|
|
@ -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. There’s no point in trying to write
|
||||
a Joy program until I’m sure I understand the problem well enough.
|
||||
|
||||
The first thing I did was to write a column of numbers from 1 to n (32
|
||||
as it happens) and next to them the desired output number, to look for
|
||||
|
|
@ -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
|
||||
Let’s figure out how, given an index into a row, we can calculate the
|
||||
value there. The index will be from 0 to :math:`k - 1`.
|
||||
|
||||
Let's look at an example, with :math:`k = 4`:
|
||||
Let’s look at an example, with :math:`k = 4`:
|
||||
|
||||
::
|
||||
|
||||
0 1 2 3 4 5 6 7
|
||||
7 6 5 4 5 6 7 8
|
||||
0 1 2 3 4 5 6 7
|
||||
7 6 5 4 5 6 7 8
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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
|
||||
(I’m leaving out details of how I figured this all out and just giving
|
||||
the relevent bits. It took a little while to zero in of the aspects of
|
||||
the pattern that were important for the task.)
|
||||
|
||||
|
|
@ -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
|
||||
I’m not mathematically sophisticated enough to turn this directly into a
|
||||
formula (but Sympy is, see below.) I’m going to write a simple Python
|
||||
function to iterate and search:
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -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 don’t know why. I’m 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 rank’s first corner and subtract it (plus 2) from the number and
|
||||
compute the offset as above and then the final output, but this overhead
|
||||
is partially shared by the other method, and overshadowed by the time it
|
||||
(the other iterative method) would take for really big inputs.
|
||||
|
|
@ -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.
|
||||
It’s 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 rank’s total places (its own and those of lesser
|
||||
rank) from our :math:`n` of rank :math:`k`. Substituting :math:`k - 1`
|
||||
for :math:`k` in :math:`k(k + 1)` gives :math:`(k - 1)(k - 1 + 1)`,
|
||||
which of course simplifies to :math:`k(k - 1)`.)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 system’s full passphrase list is available as your puzzle input. How
|
||||
many passphrases are valid?
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
from notebook_preamble import J, V, define
|
||||
|
||||
I'll assume the input is a Joy sequence of sequences of integers.
|
||||
I’ll assume the input is a Joy sequence of sequences of integers.
|
||||
|
||||
::
|
||||
|
||||
[[5 1 9 5]
|
||||
[7 5 4 3]
|
||||
[2 4 6 8]]
|
||||
[[5 1 9 5]
|
||||
[7 5 4 3]
|
||||
[2 4 6 8]]
|
||||
|
||||
So, obviously, the initial form will be a ``step`` function:
|
||||
|
||||
::
|
||||
|
||||
AoC2017.4 == 0 swap [F +] step
|
||||
AoC2017.4 == 0 swap [F +] step
|
||||
|
||||
::
|
||||
|
||||
F == [size] [unique size] cleave =
|
||||
F == [size] [unique size] cleave =
|
||||
|
||||
The ``step_zero`` combinator includes the ``0 swap`` that would normally
|
||||
open one of these definitions:
|
||||
|
|
@ -53,7 +53,7 @@ open one of these definitions:
|
|||
|
||||
::
|
||||
|
||||
AoC2017.4 == [F +] step_zero
|
||||
AoC2017.4 == [F +] step_zero
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
|
|||
|
|
@ -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, don’t jump at all).
|
||||
Fortunately, the instruction is then incremented to 1.
|
||||
|
||||
- 2 (3) 0 1 -3 - step forward because of the instruction we just
|
||||
modified. The first instruction is incremented again, now to 2.
|
||||
- 2 4 0 1 (-3) - jump all the way to the end; leave a 4 behind.
|
||||
- 2 (4) 0 1 -2 - go back to where we just were; increment -3 to -2.
|
||||
- 2 5 0 1 -2 - jump 4 steps forward, escaping the maze.
|
||||
- ::
|
||||
|
||||
2 (3) 0 1 -3 - step forward because of the instruction we just modified. The first instruction is incremented again, now to 2.
|
||||
|
||||
- ::
|
||||
|
||||
2 4 0 1 (-3) - jump all the way to the end; leave a 4 behind.
|
||||
|
||||
- ::
|
||||
|
||||
2 (4) 0 1 -2 - go back to where we just were; increment -3 to -2.
|
||||
|
||||
- ::
|
||||
|
||||
2 5 0 1 -2 - jump 4 steps forward, escaping the maze.
|
||||
|
||||
In this example, the exit is reached in 5 steps.
|
||||
|
||||
|
|
@ -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, I’m going to assume a starting state with the size of the
|
||||
sequence pre-computed. We need it to define the exit condition and it is
|
||||
a trivial preamble to generate it. We then need and ``index`` and a
|
||||
``step-count``, which are both initially zero. Then we have the sequence
|
||||
|
|
@ -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``! D’oh!
|
||||
|
||||
::
|
||||
|
||||
index step-count [...] F
|
||||
------------------------------
|
||||
step-count
|
||||
index step-count [...] F
|
||||
------------------------------
|
||||
step-count
|
||||
|
||||
So, let's start by nailing down the predicate:
|
||||
So, let’s start by nailing down the predicate:
|
||||
|
||||
::
|
||||
|
||||
F == [P] [T] [R1] [R2] genrec
|
||||
== [P] [T] [R1 [F] R2] ifte
|
||||
F == [P] [T] [R1] [R2] genrec
|
||||
== [P] [T] [R1 [F] R2] ifte
|
||||
|
||||
0 0 [0 3 0 1 -3] popop 5 >=
|
||||
0 0 [0 3 0 1 -3] popop 5 >=
|
||||
|
||||
P == popop 5 >=
|
||||
P == popop 5 >=
|
||||
|
||||
Now we need the else-part:
|
||||
|
||||
::
|
||||
|
||||
index step-count [0 3 0 1 -3] roll< popop
|
||||
index step-count [0 3 0 1 -3] roll< popop
|
||||
|
||||
E == roll< popop
|
||||
E == roll< popop
|
||||
|
||||
Last but not least, the recursive branch
|
||||
|
||||
::
|
||||
|
||||
0 0 [0 3 0 1 -3] R1 [F] R2
|
||||
0 0 [0 3 0 1 -3] R1 [F] R2
|
||||
|
||||
The ``R1`` function has a big job:
|
||||
|
||||
::
|
||||
|
||||
R1 == get the value at index
|
||||
increment the value at the index
|
||||
add the value gotten to the index
|
||||
increment the step count
|
||||
R1 == get the value at index
|
||||
increment the value at the index
|
||||
add the value gotten to the index
|
||||
increment the step count
|
||||
|
||||
The only tricky thing there is incrementing an integer in the sequence.
|
||||
Joy sequences are not particularly good for random access. We could
|
||||
encode the list of jump offsets in a big integer and use math to do the
|
||||
processing for a good speed-up, but it still wouldn't beat the
|
||||
performance of e.g. a mutable array. This is just one of those places
|
||||
where "plain vanilla" Joypy doesn't shine (in default performance. The
|
||||
processing for a good speed-up, but it still wouldn’t beat the
|
||||
performance of e.g. a mutable array. This is just one of those places
|
||||
where “plain vanilla” Joypy doesn’t shine (in default performance. The
|
||||
legendary *Sufficiently-Smart Compiler* would of course rewrite this
|
||||
function to use an array "under the hood".)
|
||||
function to use an array “under the hood”.)
|
||||
|
||||
In the meantime, I'm going to write a primitive function that just does
|
||||
In the meantime, I’m going to write a primitive function that just does
|
||||
what we need.
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -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 wouldn’t be as efficient as something written in assembly, C, or
|
||||
even Python.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
It’s 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 you’re deriving a Joy program when you have a stack
|
||||
effect for a Yin function and you need to define it. For example, in the
|
||||
Ordered Binary Trees notebook there is a point where we must derive a
|
||||
function ``Ee``:
|
||||
|
||||
::
|
||||
|
||||
[key old_value left right] new_value key [Tree-add] Ee
|
||||
------------------------------------------------------------
|
||||
[key new_value left right]
|
||||
[key old_value left right] new_value key [Tree-add] Ee
|
||||
------------------------------------------------------------
|
||||
[key new_value left right]
|
||||
|
||||
While it is not hard to come up with this function manually, there is no
|
||||
necessity. This function can be defined (in Python) directly from its
|
||||
|
|
@ -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 haven’t 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 node’s 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. I’m 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 (we’ll 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
|
||||
|
||||
|
|
|
|||
|
|
@ -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. I’m
|
||||
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
|
||||
It’s 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 let’s 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 let’s 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
|
||||
Let’s 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
|
||||
Let’s 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
|
||||
Let’s build Circuits
|
||||
====================
|
||||
|
||||
In order to work with expressions as digital circuits, let's define some
|
||||
In order to work with expressions as digital circuits, let’s define some
|
||||
helper functions that will create logic circuits out of simpler forms.
|
||||
The names of the functions below reflect the choice of Mark as Boolean
|
||||
``True`` but this is `just a convention <#Appendix:-Duals>`__.
|
||||
|
|
@ -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 let’s 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 doesn’t even bother to stop once it’s found a solution.
|
||||
|
||||
Expressions from Truth Tables
|
||||
-----------------------------
|
||||
|
||||
Sometimes we will have a function for which we know the behavior (truth
|
||||
table) but not an expression and we want the expression. For example,
|
||||
imagine that we didn't just create the expression for this table:
|
||||
imagine that we didn’t just create the expression for this table:
|
||||
|
||||
::
|
||||
|
||||
a b c | Value
|
||||
---------+------
|
||||
|
|
||||
() |
|
||||
() |
|
||||
() () | ()
|
||||
() |
|
||||
() () | ()
|
||||
() () | ()
|
||||
() () () |
|
||||
a b c | Value
|
||||
---------+------
|
||||
|
|
||||
() |
|
||||
() |
|
||||
() () | ()
|
||||
() |
|
||||
() () | ()
|
||||
() () | ()
|
||||
() () () |
|
||||
|
||||
Each Row can be Represented as an Expression
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -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, let’s
|
||||
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, it’s easy to see that the carry bit is just **AND** and the
|
||||
sum bit is just **XOR** of the two input bits.
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -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
|
||||
Let’s 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
|
||||
I’m 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.
|
||||
Let’s 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 can’t
|
||||
represent just ``a b`` as a single Python object, so we have to retain
|
||||
the outer pair of containers to hold them without inverting the
|
||||
Mark/Void value (if we just used one container.)
|
||||
|
|
@ -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 let’s trick our function, it can’t handle
|
||||
``(a ((b c))) = (a b c)`` yet. This is going to require an auxiliary
|
||||
helper function that is similar to ``simplify()`` but that yields terms
|
||||
into an outer context.
|
||||
|
|
@ -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”. I’ll come back to the
|
||||
interpretation of “Each-Way” as an ``if-then-else`` statement later.
|
||||
|
||||
The thing to note here is that the value for ``a`` can be a whole
|
||||
expression which appears twice in the new form: once next to ``b`` and
|
||||
|
|
@ -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
|
||||
Let’s redefine the ``full_bit_adder()`` function with the smallest
|
||||
version of each above.
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -2103,8 +2103,8 @@ other two.
|
|||
`Davis–Putnam–Logemann–Loveland (DPLL) algorithm <https://en.wikipedia.org/wiki/Davis%E2%80%93Putnam%E2%80%93Logemann%E2%80%93Loveland_algorithm>`__ SAT Solver
|
||||
===============================================================================================================================================================
|
||||
|
||||
This is something of an Interlude, we aren't going to use it below, but
|
||||
it's too cool to omit mention.
|
||||
This is something of an Interlude, we aren’t going to use it below, but
|
||||
it’s too cool to omit mention.
|
||||
|
||||
We can use the ``simplify()`` function to create a more efficient SAT
|
||||
solver along the lines of the DPLL algorithm.
|
||||
|
|
@ -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 doesn’t
|
||||
prevent the ``simplify()`` function from reducing the form to the Mark.
|
||||
This should be the case for all solutions generated by the
|
||||
``dpll_iter()`` function.
|
||||
|
|
@ -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 I’m 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, let’s formalize it and make it a little easier to
|
||||
work with.
|
||||
|
||||
First let's have a *register* of named values:
|
||||
First let’s have a *register* of named values:
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
R = {name: Void for name in 'Cin a3 a2 a1 a0 b3 b2 b1 b0 Cout'.split()}
|
||||
|
||||
Let's have a *program* of named expressions that give new values when
|
||||
Let’s have a *program* of named expressions that give new values when
|
||||
evaluated in terms of the current values in **R** (this is just the same
|
||||
``CIRCUITS``, but feeding back the results into the "b" bits):
|
||||
``CIRCUITS``, but feeding back the results into the “b” bits):
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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.
|
||||
Let’s 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
|
||||
Let’s set one bit to true (Mark-valued in the chosen convention. We
|
||||
could have Void be true but we would have to form the circuit
|
||||
expressions differently.)
|
||||
|
||||
|
|
@ -3058,7 +3058,7 @@ expressions differently.)
|
|||
|
||||
R['a0'] = Mark
|
||||
|
||||
Now let's count to twenty.
|
||||
Now let’s 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 isn’t
|
||||
necessary, we can run the cycles and just ``reify()`` without reducing
|
||||
and we get new circuits that define bits in terms of the register values
|
||||
N cycles in the past.
|
||||
|
|
@ -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 P’s 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
|
||||
We’ll assume a single ``WRITE`` bit that sets a RAM location determined
|
||||
by the ``ADDR`` sub-register to the contents of the ``DATA``
|
||||
sub-register.
|
||||
|
||||
|
|
@ -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 terms’s 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()`` let’s define a function
|
||||
that reduces a form to a (hopefully) smaller equivalent form by going
|
||||
through all the variables in the form and using ``standard_form()`` with
|
||||
each. Along with clean and unwrap we can drive an expression to a fixed
|
||||
|
|
@ -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
|
||||
Let’s 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 it’s 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:
|
||||
Let’s simplify the first one manually just for fun:
|
||||
|
||||
::
|
||||
|
||||
(((((())) (())) ((()))))
|
||||
(( ) ) ( )
|
||||
( )
|
||||
(((((())) (())) ((()))))
|
||||
(( ) ) ( )
|
||||
( )
|
||||
|
||||
Sure enough, it reduces to Mark after just a few applications of the
|
||||
rule ``(()) = __`` (the underscores indicates the absence of any value,
|
||||
|
|
@ -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.
|
||||
Let’s try using ``each_way()`` with the most common names in the form.
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
|
|||
|
|
@ -1,69 +1,69 @@
|
|||
∂RE
|
||||
===
|
||||
|
||||
Brzozowski's Derivatives of Regular Expressions
|
||||
Brzozowski’s Derivatives of Regular Expressions
|
||||
-----------------------------------------------
|
||||
|
||||
Legend:
|
||||
|
||||
::
|
||||
|
||||
∧ intersection
|
||||
∨ union
|
||||
∘ concatenation (see below)
|
||||
¬ complement
|
||||
ϕ empty set (aka ∅)
|
||||
λ singleton set containing just the empty string
|
||||
I set of all letters in alphabet
|
||||
∧ intersection
|
||||
∨ union
|
||||
∘ concatenation (see below)
|
||||
¬ complement
|
||||
ϕ empty set (aka ∅)
|
||||
λ singleton set containing just the empty string
|
||||
I set of all letters in alphabet
|
||||
|
||||
Derivative of a set ``R`` of strings and a string ``a``:
|
||||
|
||||
::
|
||||
|
||||
∂a(R)
|
||||
∂a(R)
|
||||
|
||||
∂a(a) → λ
|
||||
∂a(λ) → ϕ
|
||||
∂a(ϕ) → ϕ
|
||||
∂a(¬a) → ϕ
|
||||
∂a(R*) → ∂a(R)∘R*
|
||||
∂a(¬R) → ¬∂a(R)
|
||||
∂a(R∘S) → ∂a(R)∘S ∨ δ(R)∘∂a(S)
|
||||
∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
|
||||
∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
|
||||
∂a(a) → λ
|
||||
∂a(λ) → ϕ
|
||||
∂a(ϕ) → ϕ
|
||||
∂a(¬a) → ϕ
|
||||
∂a(R*) → ∂a(R)∘R*
|
||||
∂a(¬R) → ¬∂a(R)
|
||||
∂a(R∘S) → ∂a(R)∘S ∨ δ(R)∘∂a(S)
|
||||
∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
|
||||
∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
|
||||
|
||||
∂ab(R) = ∂b(∂a(R))
|
||||
∂ab(R) = ∂b(∂a(R))
|
||||
|
||||
Auxiliary predicate function ``δ`` (I call it ``nully``) returns either
|
||||
``λ`` if ``λ ⊆ R`` or ``ϕ`` otherwise:
|
||||
|
||||
::
|
||||
|
||||
δ(a) → ϕ
|
||||
δ(λ) → λ
|
||||
δ(ϕ) → ϕ
|
||||
δ(R*) → λ
|
||||
δ(¬R) δ(R)≟ϕ → λ
|
||||
δ(¬R) δ(R)≟λ → ϕ
|
||||
δ(R∘S) → δ(R) ∧ δ(S)
|
||||
δ(R ∧ S) → δ(R) ∧ δ(S)
|
||||
δ(R ∨ S) → δ(R) ∨ δ(S)
|
||||
δ(a) → ϕ
|
||||
δ(λ) → λ
|
||||
δ(ϕ) → ϕ
|
||||
δ(R*) → λ
|
||||
δ(¬R) δ(R)≟ϕ → λ
|
||||
δ(¬R) δ(R)≟λ → ϕ
|
||||
δ(R∘S) → δ(R) ∧ δ(S)
|
||||
δ(R ∧ S) → δ(R) ∧ δ(S)
|
||||
δ(R ∨ S) → δ(R) ∨ δ(S)
|
||||
|
||||
Some rules we will use later for "compaction":
|
||||
Some rules we will use later for “compaction”:
|
||||
|
||||
::
|
||||
|
||||
R ∧ ϕ = ϕ ∧ R = ϕ
|
||||
R ∧ ϕ = ϕ ∧ R = ϕ
|
||||
|
||||
R ∧ I = I ∧ R = R
|
||||
R ∧ I = I ∧ R = R
|
||||
|
||||
R ∨ ϕ = ϕ ∨ R = R
|
||||
R ∨ ϕ = ϕ ∨ R = R
|
||||
|
||||
R ∨ I = I ∨ R = I
|
||||
R ∨ I = I ∨ R = I
|
||||
|
||||
R∘ϕ = ϕ∘R = ϕ
|
||||
R∘ϕ = ϕ∘R = ϕ
|
||||
|
||||
R∘λ = λ∘R = R
|
||||
R∘λ = λ∘R = R
|
||||
|
||||
Concatination of sets: for two sets A and B the set A∘B is defined as:
|
||||
|
||||
|
|
@ -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
|
||||
I’m only going to use two symbols (at first) becaase this is enough to
|
||||
illustrate the algorithm and because you can represent any other
|
||||
alphabet with two symbols (if you had to.)
|
||||
|
||||
I chose the names ``O`` and ``l`` (uppercase "o" and lowercase "L") to
|
||||
I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
|
||||
look like ``0`` and ``1`` (zero and one) respectively.
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -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 I’m going to use tagged tuples. A *regular
|
||||
expression* is one of:
|
||||
|
||||
::
|
||||
|
||||
O
|
||||
l
|
||||
(KSTAR, R)
|
||||
(NOT, R)
|
||||
(AND, R, S)
|
||||
(CONS, R, S)
|
||||
(OR, R, S)
|
||||
O
|
||||
l
|
||||
(KSTAR, R)
|
||||
(NOT, R)
|
||||
(AND, R, S)
|
||||
(CONS, R, S)
|
||||
(OR, R, S)
|
||||
|
||||
Where ``R`` and ``S`` stand for *regular expressions*.
|
||||
|
||||
|
|
@ -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.
|
||||
Let’s 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...
|
||||
-------------------
|
||||
Let’s 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 you’ll see that we never use the “set-ness” of the symbols ``O``
|
||||
and ``l``. The only time Python set operators (``&`` and ``|``) appear
|
||||
is in the ``nully()`` function, and there they operate on (recursively
|
||||
computed) outputs of that function, never ``O`` and ``l``.
|
||||
|
|
@ -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 1’s and not ending in 01 nor composed of all 1’s.”
|
||||
|
||||
.. 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/>`__.) You’ll see that only
|
||||
paths that lead to one of the accepting states will match the regular
|
||||
expression. All other paths will terminate at one of the non-accepting
|
||||
states.
|
||||
|
||||
There's a happy path to ``g`` along 111:
|
||||
There’s a happy path to ``g`` along 111:
|
||||
|
||||
::
|
||||
|
||||
a→c→e→g
|
||||
a→c→e→g
|
||||
|
||||
After you reach ``g`` you're stuck there eating 1's until you see a 0,
|
||||
which takes you to the ``i→j→i|i→j→h→i`` "trap". You can't reach any
|
||||
After you reach ``g`` you’re stuck there eating 1’s until you see a 0,
|
||||
which takes you to the ``i→j→i|i→j→h→i`` “trap”. You can’t reach any
|
||||
other states from those two loops.
|
||||
|
||||
If you see a 0 before you see 111 you will reach ``b``, which forms
|
||||
another "trap" with ``d`` and ``f``. The only way out is another happy
|
||||
another “trap” with ``d`` and ``f``. The only way out is another happy
|
||||
path along 111 to ``h``:
|
||||
|
||||
::
|
||||
|
||||
b→d→f→h
|
||||
b→d→f→h
|
||||
|
||||
Once you have reached ``h`` you can see as many 1's or as many 0' in a
|
||||
row and still be either still at ``h`` (for 1's) or move to ``i`` (for
|
||||
0's). If you find yourself at ``i`` you can see as many 0's, or
|
||||
Once you have reached ``h`` you can see as many 1’s or as many 0’ in a
|
||||
row and still be either still at ``h`` (for 1’s) or move to ``i`` (for
|
||||
0’s). If you find yourself at ``i`` you can see as many 0’s, or
|
||||
repetitions of 10, as there are, but if you see just a 1 you move to
|
||||
``j``.
|
||||
|
||||
|
|
@ -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 arrow’s symbol.
|
||||
|
||||
If we label the initial RE ``a``, we can say:
|
||||
|
||||
::
|
||||
|
||||
a --0--> ∂0(a)
|
||||
a --1--> ∂1(a)
|
||||
a --0--> ∂0(a)
|
||||
a --1--> ∂1(a)
|
||||
|
||||
And so on, each new unique RE is a new state in the FSM table.
|
||||
|
||||
|
|
@ -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`` isn’t.
|
||||
|
||||
.. 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)*
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
Let’s 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:
|
||||
Let’s 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 you’ll see that we might be
|
||||
interested in generating an endless cycle of:
|
||||
|
||||
::
|
||||
|
||||
3 2 1 3 1 2 3
|
||||
3 2 1 3 1 2 3
|
||||
|
||||
To do this we want to encode the numbers as pairs of bits in a single
|
||||
int:
|
||||
|
||||
::
|
||||
|
||||
3 2 1 3 1 2 3
|
||||
0b 11 10 01 11 01 10 11 == 14811
|
||||
3 2 1 3 1 2 3
|
||||
0b 11 10 01 11 01 10 11 == 14811
|
||||
|
||||
And pick them off by masking with 3 (binary 11) and then shifting the
|
||||
int right two bits.
|
||||
|
|
@ -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
|
||||
that’s a little beyond the scope of this article. This solution does
|
||||
extra work, but not much, and we’re not using it “in production” as they
|
||||
say.)
|
||||
|
||||
Run 466 times
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
In the PE1 problem we are asked to sum all the multiples of three and
|
||||
five less than 1000. It's worked out that we need to use all seven
|
||||
five less than 1000. It’s worked out that we need to use all seven
|
||||
numbers sixty-six times and then four more.
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -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``:
|
||||
Let’s start with ``swons``:
|
||||
|
||||
::
|
||||
|
||||
[b a F] b+a swons
|
||||
[b+a b a F]
|
||||
[b a F] b+a swons
|
||||
[b+a b a F]
|
||||
|
||||
Considering this quote as a stack:
|
||||
|
||||
::
|
||||
|
||||
F a b b+a
|
||||
F a b b+a
|
||||
|
||||
We want to get it to:
|
||||
|
||||
::
|
||||
|
||||
F b b+a b
|
||||
F b b+a b
|
||||
|
||||
So:
|
||||
|
||||
::
|
||||
|
||||
F a b b+a popdd over
|
||||
F b b+a b
|
||||
F a b b+a popdd over
|
||||
F b b+a b
|
||||
|
||||
And therefore:
|
||||
|
||||
::
|
||||
|
||||
[b+a b a F] [popdd over] infra
|
||||
[b b+a b F]
|
||||
[b+a b a F] [popdd over] infra
|
||||
[b b+a b F]
|
||||
|
||||
But we can just use ``cons`` to carry ``b+a`` into the quote:
|
||||
|
||||
::
|
||||
|
||||
[b a F] b+a [popdd over] cons infra
|
||||
[b a F] [b+a popdd over] infra
|
||||
[b b+a b F]
|
||||
[b a F] b+a [popdd over] cons infra
|
||||
[b a F] [b+a popdd over] infra
|
||||
[b b+a b F]
|
||||
|
||||
Lastly:
|
||||
|
||||
::
|
||||
|
||||
[b b+a b F] uncons
|
||||
b [b+a b F]
|
||||
[b b+a b F] uncons
|
||||
b [b+a b F]
|
||||
|
||||
Putting it all together:
|
||||
|
||||
::
|
||||
|
||||
F == + [popdd over] cons infra uncons
|
||||
fib_gen == [1 1 F]
|
||||
F == + [popdd over] cons infra uncons
|
||||
fib_gen == [1 1 F]
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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 it’s straightforward to define ``PE2`` as a recursive function that
|
||||
generates terms in the Fibonacci sequence until they exceed four million
|
||||
and sums the even ones.
|
||||
|
||||
|
|
@ -503,18 +502,18 @@ and sums the even ones.
|
|||
4613732
|
||||
|
||||
|
||||
Here's the collected program definitions:
|
||||
Here’s the collected program definitions:
|
||||
|
||||
::
|
||||
|
||||
fib == + swons [popdd over] infra uncons
|
||||
fib_gen == [1 1 fib]
|
||||
fib == + swons [popdd over] infra uncons
|
||||
fib_gen == [1 1 fib]
|
||||
|
||||
even == dup 2 %
|
||||
>4M == 4000000 >
|
||||
even == dup 2 %
|
||||
>4M == 4000000 >
|
||||
|
||||
PE2.1 == even [+] [pop] branch
|
||||
PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
|
||||
PE2.1 == even [+] [pop] branch
|
||||
PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
|
||||
|
||||
Even-valued Fibonacci Terms
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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 let’s use a function that, given a positive
|
||||
integer, returns the sum of all positive integers less than that one.
|
||||
(In this case the types A and B are both ``int``.) ### With ``range()``
|
||||
and ``sum()``
|
||||
|
|
@ -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 doesn’t help much.
|
||||
|
||||
::
|
||||
|
||||
c [F] . catamorphism
|
||||
c [F] . [[] =] roll> [uncons swap] swap hylomorphism
|
||||
c [F] [[] =] . roll> [uncons swap] swap hylomorphism
|
||||
[[] =] c [F] [uncons swap] . swap hylomorphism
|
||||
[[] =] c [uncons swap] [F] . hylomorphism
|
||||
[[] =] c [uncons swap] [F] [unit [pop] swoncat] . dipd [dip] swoncat genrec
|
||||
[[] =] c . unit [pop] swoncat [uncons swap] [F] [dip] swoncat genrec
|
||||
[[] =] [c] [pop] . swoncat [uncons swap] [F] [dip] swoncat genrec
|
||||
[[] =] [pop c] [uncons swap] [F] [dip] . swoncat genrec
|
||||
[[] =] [pop c] [uncons swap] [dip F] genrec
|
||||
c [F] . catamorphism
|
||||
c [F] . [[] =] roll> [uncons swap] swap hylomorphism
|
||||
c [F] [[] =] . roll> [uncons swap] swap hylomorphism
|
||||
[[] =] c [F] [uncons swap] . swap hylomorphism
|
||||
[[] =] c [uncons swap] [F] . hylomorphism
|
||||
[[] =] c [uncons swap] [F] [unit [pop] swoncat] . dipd [dip] swoncat genrec
|
||||
[[] =] c . unit [pop] swoncat [uncons swap] [F] [dip] swoncat genrec
|
||||
[[] =] [c] [pop] . swoncat [uncons swap] [F] [dip] swoncat genrec
|
||||
[[] =] [pop c] [uncons swap] [F] [dip] . swoncat genrec
|
||||
[[] =] [pop c] [uncons swap] [dip F] genrec
|
||||
|
||||
Because the arguments to catamorphism have to be prepared (unlike the
|
||||
arguments to anamorphism, which only need to be rearranged slightly)
|
||||
there isn't much point to "pre-cooking" the definition.
|
||||
there isn’t much point to “pre-cooking” the definition.
|
||||
|
||||
::
|
||||
|
||||
catamorphism == [[] =] roll> [uncons swap] swap hylomorphism
|
||||
catamorphism == [[] =] roll> [uncons swap] swap hylomorphism
|
||||
|
||||
An example of a catamorphism is the sum function.
|
||||
|
||||
::
|
||||
|
||||
sum == 0 [+] catamorphism
|
||||
sum == 0 [+] catamorphism
|
||||
|
||||
"Fusion Law" for catas (UNFINISHED!!!)
|
||||
“Fusion Law” for catas (UNFINISHED!!!)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
I'm not sure exactly how to translate the "Fusion Law" for catamorphisms
|
||||
I’m not sure exactly how to translate the “Fusion Law” for catamorphisms
|
||||
into Joy.
|
||||
|
||||
I know that a ``map`` composed with a cata can be expressed as a new
|
||||
|
|
@ -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 isn’t the one described in “Bananas…”. That’s more like:
|
||||
|
||||
A cata composed with some function can be expressed as some other cata:
|
||||
|
||||
::
|
||||
|
||||
b [B] catamorphism F == c [C] catamorphism
|
||||
b [B] catamorphism F == c [C] catamorphism
|
||||
|
||||
Given:
|
||||
|
||||
::
|
||||
|
||||
b F == c
|
||||
b F == c
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
B F == [F] dip C
|
||||
B F == [F] dip C
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
b[B]cata F == c[C]cata
|
||||
b[B]cata F == c[C]cata
|
||||
|
||||
F(B(head, tail)) == C(head, F(tail))
|
||||
F(B(head, tail)) == C(head, F(tail))
|
||||
|
||||
1 [2 3] B F 1 [2 3] F C
|
||||
1 [2 3] B F 1 [2 3] F C
|
||||
|
||||
|
||||
b F == c
|
||||
B F == F C
|
||||
b F == c
|
||||
B F == F C
|
||||
|
||||
b [B] catamorphism F == c [C] catamorphism
|
||||
b [B] catamorphism F == b F [C] catamorphism
|
||||
b [B] catamorphism F == c [C] catamorphism
|
||||
b [B] catamorphism F == b F [C] catamorphism
|
||||
|
||||
...
|
||||
...
|
||||
|
||||
Or maybe,
|
||||
|
||||
::
|
||||
|
||||
[F] map b [B] cata == c [C] cata ???
|
||||
[F] map b [B] cata == c [C] cata ???
|
||||
|
||||
[F] map b [B] cata == b [F B] cata I think this is generally true, unless F consumes stack items
|
||||
instead of just transforming TOS. Of course, there's always [F] unary.
|
||||
b [F] unary [[F] unary B] cata
|
||||
[F] map b [B] cata == b [F B] cata I think this is generally true, unless F consumes stack items
|
||||
instead of just transforming TOS. Of course, there's always [F] unary.
|
||||
b [F] unary [[F] unary B] cata
|
||||
|
||||
[10 *] map 0 swap [+] step == 0 swap [10 * +] step
|
||||
[10 *] map 0 swap [+] step == 0 swap [10 * +] step
|
||||
|
||||
For example:
|
||||
|
||||
::
|
||||
|
||||
F == 10 *
|
||||
b == 0
|
||||
B == +
|
||||
c == 0
|
||||
C == F +
|
||||
F == 10 *
|
||||
b == 0
|
||||
B == +
|
||||
c == 0
|
||||
C == F +
|
||||
|
||||
b F == c
|
||||
0 10 * == 0
|
||||
b F == c
|
||||
0 10 * == 0
|
||||
|
||||
B F == [F] dip C
|
||||
+ 10 * == [10 *] dip F +
|
||||
+ 10 * == [10 *] dip 10 * +
|
||||
B F == [F] dip C
|
||||
+ 10 * == [10 *] dip F +
|
||||
+ 10 * == [10 *] dip 10 * +
|
||||
|
||||
n m + 10 * == 10(n+m)
|
||||
n m + 10 * == 10(n+m)
|
||||
|
||||
n m [10 *] dip 10 * +
|
||||
n 10 * m 10 * +
|
||||
10n m 10 * +
|
||||
10n 10m +
|
||||
10n+10m
|
||||
n m [10 *] dip 10 * +
|
||||
n 10 * m 10 * +
|
||||
10n m 10 * +
|
||||
10n 10m +
|
||||
10n+10m
|
||||
|
||||
10n+10m = 10(n+m)
|
||||
10n+10m = 10(n+m)
|
||||
|
||||
Ergo:
|
||||
|
||||
::
|
||||
|
||||
0 [+] catamorphism 10 * == 0 [10 * +] catamorphism
|
||||
0 [+] catamorphism 10 * == 0 [10 * +] catamorphism
|
||||
|
||||
The ``step`` combinator will usually be better to use than ``catamorphism``.
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
sum == 0 swap [+] step
|
||||
sum == 0 [+] catamorphism
|
||||
sum == 0 swap [+] step
|
||||
sum == 0 [+] catamorphism
|
||||
|
||||
anamorphism catamorphism == hylomorphism
|
||||
========================================
|
||||
|
|
@ -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
|
||||
There’s no way to do that with the ``paramorphism`` combinator as
|
||||
defined. We would have to write and use a slightly different recursion
|
||||
combinator that accepted an additional "preprocessor" function ``[H]``
|
||||
combinator that accepted an additional “preprocessor” function ``[H]``
|
||||
and built:
|
||||
|
||||
::
|
||||
|
||||
n swap [P] [pop] [H [F] dupdip G] primrec
|
||||
n swap [P] [pop] [H [F] dupdip G] primrec
|
||||
|
||||
Or just write it out manually. This is yet another place where the
|
||||
*sufficiently smart compiler* will one day automatically refactor the
|
||||
|
|
@ -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.
|
||||
generator’s output.
|
||||
|
||||
::
|
||||
|
||||
H == [P] [pop c] [G ] [dip F] genrec
|
||||
H == c swap [P] [pop] [G [F] dip ] [i] genrec
|
||||
H == [P] [pop c] [ [G] dupdip ] [dip F] genrec
|
||||
H == c swap [P] [pop] [ [F] dupdip G] [i] genrec
|
||||
H == [P] [pop c] [G ] [dip F] genrec
|
||||
H == c swap [P] [pop] [G [F] dip ] [i] genrec
|
||||
H == [P] [pop c] [ [G] dupdip ] [dip F] genrec
|
||||
H == c swap [P] [pop] [ [F] dupdip G] [i] genrec
|
||||
|
||||
Consider:
|
||||
|
||||
::
|
||||
|
||||
... a G [H] dip F w/ a G == a' b
|
||||
... c a G [F] dip H a G == b a'
|
||||
... a [G] dupdip [H] dip F a G == a'
|
||||
... c a [F] dupdip G H a G == a'
|
||||
... a G [H] dip F w/ a G == a' b
|
||||
... c a G [F] dip H a G == b a'
|
||||
... a [G] dupdip [H] dip F a G == a'
|
||||
... c a [F] dupdip G H a G == a'
|
||||
|
||||
1
|
||||
~
|
||||
|
||||
::
|
||||
|
||||
H == [P] [pop c] [G] [dip F] genrec
|
||||
H == [P] [pop c] [G] [dip F] genrec
|
||||
|
||||
Iterate n times.
|
||||
|
||||
::
|
||||
|
||||
... a [P] [pop c] [G] [dip F] genrec
|
||||
... a G [H] dip F
|
||||
... a' b [H] dip F
|
||||
... a' H b F
|
||||
... a' G [H] dip F b F
|
||||
... a'' b [H] dip F b F
|
||||
... a'' H b F b F
|
||||
... a'' G [H] dip F b F b F
|
||||
... a''' b [H] dip F b F b F
|
||||
... a''' H b F b F b F
|
||||
... a''' pop c b F b F b F
|
||||
... c b F b F b F
|
||||
... a [P] [pop c] [G] [dip F] genrec
|
||||
... a G [H] dip F
|
||||
... a' b [H] dip F
|
||||
... a' H b F
|
||||
... a' G [H] dip F b F
|
||||
... a'' b [H] dip F b F
|
||||
... a'' H b F b F
|
||||
... a'' G [H] dip F b F b F
|
||||
... a''' b [H] dip F b F b F
|
||||
... a''' H b F b F b F
|
||||
... a''' pop c b F b F b F
|
||||
... c b F b F b F
|
||||
|
||||
This form builds up a continuation that contains the intermediate
|
||||
results along with the pending combiner functions. When the base case is
|
||||
reached the last term is replaced by the identity value c and the
|
||||
continuation "collapses" into the final result.
|
||||
continuation “collapses” into the final result.
|
||||
|
||||
2
|
||||
~
|
||||
|
|
@ -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 didn’t
|
||||
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.”
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
|
||||
`Newton’s method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
|
||||
=====================================================================
|
||||
|
||||
Let's use the Newton-Raphson method for finding the root of an equation
|
||||
Let’s use the Newton-Raphson method for finding the root of an equation
|
||||
to write a function that can compute the square root of a number.
|
||||
|
||||
Cf. `"Why Functional Programming Matters" by John
|
||||
Cf. `“Why Functional Programming Matters” by John
|
||||
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -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 we’re writing. If we let 1 be the initial approximation:
|
||||
|
||||
::
|
||||
|
||||
1 n 1 / + 2 /
|
||||
1 n/1 + 2 /
|
||||
1 n + 2 /
|
||||
n+1 2 /
|
||||
(n+1)/2
|
||||
1 n 1 / + 2 /
|
||||
1 n/1 + 2 /
|
||||
1 n + 2 /
|
||||
n+1 2 /
|
||||
(n+1)/2
|
||||
|
||||
The generator can be written as:
|
||||
|
||||
::
|
||||
|
||||
23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 23 [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 [23 over / + 2 /] [dup] swoncat make_generator
|
||||
1 [dup 23 over / + 2 /] make_generator
|
||||
23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 23 [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 [23 over / + 2 /] [dup] swoncat make_generator
|
||||
1 [dup 23 over / + 2 /] make_generator
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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...
|
||||
Let’s 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
|
|
@ -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 it’s the definition of the ``quadratic`` function:
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
|
||||
|
||||
Let's try it out:
|
||||
Let’s try it out:
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Let’s write a function that, given a positive integer, returns the sum
|
||||
of all positive integers less than that one. (In this case the types
|
||||
``A``, ``B`` and ``C`` are all ``int``.)
|
||||
|
||||
|
|
@ -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:
|
||||
Let’s 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
|
||||
generator’s output, in other words, whether ``F`` or ``G`` should run
|
||||
first in the recursive branch.
|
||||
|
||||
::
|
||||
|
||||
H1 == [P] [pop c] [G ] [dip F] genrec
|
||||
H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
|
||||
H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
|
||||
H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
|
||||
H1 == [P] [pop c] [G ] [dip F] genrec
|
||||
H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
|
||||
H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
|
||||
H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
|
||||
|
||||
The working of the generator function ``G`` differs slightly for each.
|
||||
Consider the recursive branches:
|
||||
|
||||
::
|
||||
|
||||
... a G [H1] dip F w/ a G == a′ b
|
||||
... a G [H1] dip F w/ a G == a′ b
|
||||
|
||||
... c a G [F] dip H2 a G == b a′
|
||||
... c a G [F] dip H2 a G == b a′
|
||||
|
||||
... a [G] dupdip [H3] dip F a G == a′
|
||||
... a [G] dupdip [H3] dip F a G == a′
|
||||
|
||||
... c a [F] dupdip G H4 a G == a′
|
||||
... c a [F] dupdip G H4 a G == a′
|
||||
|
||||
The following four sections illustrate how these work, omitting the
|
||||
predicate evaluation.
|
||||
|
|
@ -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 you’ll see that the combiner ``F`` only
|
||||
gets to operate on the results of ``G``, it never “sees” the first value
|
||||
``a``. If the combiner and the generator both need to work on the
|
||||
current value then ``dup`` must be used, and the generator must produce
|
||||
one item instead of two (the b is instead the duplicate of a.)
|
||||
|
||||
::
|
||||
|
||||
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
|
||||
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
|
||||
|
||||
... a [G] dupdip [H3] dip F
|
||||
... a G a [H3] dip F
|
||||
... a′ a [H3] dip F
|
||||
... a′ H3 a F
|
||||
... a′ [G] dupdip [H3] dip F a F
|
||||
... a′ G a′ [H3] dip F a F
|
||||
... a″ a′ [H3] dip F a F
|
||||
... a″ H3 a′ F a F
|
||||
... a″ [G] dupdip [H3] dip F a′ F a F
|
||||
... a″ G a″ [H3] dip F a′ F a F
|
||||
... a‴ a″ [H3] dip F a′ F a F
|
||||
... a‴ H3 a″ F a′ F a F
|
||||
... a‴ pop c a″ F a′ F a F
|
||||
... c a″ F a′ F a F
|
||||
... d a′ F a F
|
||||
... d′ a F
|
||||
... d″
|
||||
... a [G] dupdip [H3] dip F
|
||||
... a G a [H3] dip F
|
||||
... a′ a [H3] dip F
|
||||
... a′ H3 a F
|
||||
... a′ [G] dupdip [H3] dip F a F
|
||||
... a′ G a′ [H3] dip F a F
|
||||
... a″ a′ [H3] dip F a F
|
||||
... a″ H3 a′ F a F
|
||||
... a″ [G] dupdip [H3] dip F a′ F a F
|
||||
... a″ G a″ [H3] dip F a′ F a F
|
||||
... a‴ a″ [H3] dip F a′ F a F
|
||||
... a‴ H3 a″ F a′ F a F
|
||||
... a‴ pop c a″ F a′ F a F
|
||||
... c a″ F a′ F a F
|
||||
... d a′ F a F
|
||||
... d′ a F
|
||||
... d″
|
||||
|
||||
``H4``
|
||||
~~~~~~
|
||||
|
|
@ -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.”
|
||||
|
|
|
|||
|
|
@ -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, there’s no function that does that. Adding a new
|
||||
function to the dictionary is a meta-interpreter action, you have to do
|
||||
it in Python, not Joy.
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 doesn’t *have*
|
||||
to be Boolean because Python’s rules for “truthiness” will be used to
|
||||
evaluate it. I reflect this in the structure of the stack effect comment
|
||||
of ``branch``, it will only accept Boolean values, and in the definition
|
||||
of ``ifte`` above by including ``not`` in the quote, which also has the
|
||||
|
|
@ -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 couldn’t be
|
||||
reimplemented in terms of e.g. Python threads. I am not concerned with
|
||||
performance of the system just yet, only the elegance of the code it
|
||||
allows us to write.
|
||||
|
||||
|
|
@ -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.)
|
||||
Elliott’s “Compiling to Categories” paper, et. al.)
|
||||
|
||||
Just a thought, if you ``cleave`` two jobs and one requires more time to
|
||||
finish than the other you'd like to be able to assign resources
|
||||
finish than the other you’d like to be able to assign resources
|
||||
accordingly so that they both finish at the same time.
|
||||
|
||||
"Apply" Functions
|
||||
“Apply” Functions
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are also ``app2`` and ``app3`` which run a single quote on more
|
||||
|
|
@ -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
|
||||
(I’m not sure why ``cleave`` was specified to take that value, I may
|
||||
make a combinator that does the same thing but without expecting a
|
||||
value.)
|
||||
|
||||
::
|
||||
|
||||
clv == [i] app2
|
||||
clv == [i] app2
|
||||
|
||||
[A] [B] clv
|
||||
------------------
|
||||
a b
|
||||
[A] [B] clv
|
||||
------------------
|
||||
a b
|
||||
|
||||
``map``
|
||||
~~~~~~~
|
||||
|
|
@ -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`` couldn’t 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 I’m not going to worry about
|
||||
it. (And I think the Categories can deal with it anyhow? Incremental
|
||||
evaluation, yeah?)
|
||||
|
|
|
|||
1016
docs/Trees.rst
1016
docs/Trees.rst
File diff suppressed because it is too large
Load Diff
|
|
@ -1,8 +1,8 @@
|
|||
Treating Trees II: ``treestep``
|
||||
===============================
|
||||
|
||||
Let's consider a tree structure, similar to one described `"Why
|
||||
functional programming matters" by John
|
||||
Let’s consider a tree structure, similar to one described `“Why
|
||||
functional programming matters” by John
|
||||
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__,
|
||||
that consists of a node value followed by zero or more child trees. (The
|
||||
asterisk is meant to indicate the `Kleene
|
||||
|
|
@ -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 we’ll 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``.
|
||||
Let’s dive in. First, unquote the node and ``dip`` ``N``.
|
||||
|
||||
::
|
||||
|
||||
[node tree*] uncons [N] dip
|
||||
node [tree*] [N] dip
|
||||
node N [tree*]
|
||||
[node tree*] uncons [N] dip
|
||||
node [tree*] [N] dip
|
||||
node N [tree*]
|
||||
|
||||
Next, ``map`` ``K`` over the child trees and combine with ``C``.
|
||||
|
||||
::
|
||||
|
||||
node N [tree*] [K] map C
|
||||
node N [tree*] [K] map C
|
||||
node N [K.tree*] C
|
||||
node N [tree*] [K] map C
|
||||
node N [tree*] [K] map C
|
||||
node N [K.tree*] C
|
||||
|
||||
So:
|
||||
|
||||
::
|
||||
|
||||
J == uncons [N] dip [K] map C
|
||||
J == uncons [N] dip [K] map C
|
||||
|
||||
Plug it in and convert to ``genrec``:
|
||||
|
||||
::
|
||||
|
||||
K == [not] [B] [J ] ifte
|
||||
== [not] [B] [uncons [N] dip [K] map C] ifte
|
||||
== [not] [B] [uncons [N] dip] [map C] genrec
|
||||
K == [not] [B] [J ] ifte
|
||||
== [not] [B] [uncons [N] dip [K] map C] ifte
|
||||
== [not] [B] [uncons [N] dip] [map C] genrec
|
||||
|
||||
Extract the givens to parameterize the program.
|
||||
-----------------------------------------------
|
||||
|
|
@ -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 doesn’t 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
|
||||
Doesn’t work because ``map`` extracts the ``first`` item of whatever its
|
||||
mapped function produces. We have to return a list, rather than
|
||||
depositing our results directly on the stack.
|
||||
|
||||
::
|
||||
|
||||
[key value] N [left right] [K] map C
|
||||
[key value] N [left right] [K] map C
|
||||
|
||||
[key value] first [left right] [K] map flatten cons
|
||||
key [left right] [K] map flatten cons
|
||||
key [[lk] [rk] ] flatten cons
|
||||
key [ lk rk ] cons
|
||||
[key lk rk ]
|
||||
[key value] first [left right] [K] map flatten cons
|
||||
key [left right] [K] map flatten cons
|
||||
key [[lk] [rk] ] flatten cons
|
||||
key [ lk rk ] cons
|
||||
[key lk rk ]
|
||||
|
||||
So:
|
||||
|
||||
::
|
||||
|
||||
[] [first] [flatten cons] treestep
|
||||
[] [first] [flatten cons] treestep
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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 doesn’t include the ``map`` combinator, so
|
||||
the ``[C]`` function must arrange to use some combinator on the quoted
|
||||
recursive copy ``[K]``. With this function, the pattern for processing a
|
||||
non-empty node is:
|
||||
|
||||
::
|
||||
|
||||
node N [tree*] [K] C
|
||||
node N [tree*] [K] C
|
||||
|
||||
Plugging in our BTree structure:
|
||||
|
||||
::
|
||||
|
||||
[key value] N [left right] [K] C
|
||||
[key value] N [left right] [K] C
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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
|
||||
We’ll start by saying that the base-case (the key is not in the tree) is
|
||||
user defined, and the per-node function is just the query key literal:
|
||||
|
||||
::
|
||||
|
||||
[B] [query_key] [C] treegrind
|
||||
[B] [query_key] [C] treegrind
|
||||
|
||||
This means we just have to define ``C`` from:
|
||||
|
||||
::
|
||||
|
||||
[key value] query_key [left right] [K] C
|
||||
[key value] query_key [left right] [K] C
|
||||
|
||||
Let's try ``cmp``:
|
||||
Let’s try ``cmp``:
|
||||
|
||||
::
|
||||
|
||||
C == P [T>] [E] [T<] cmp
|
||||
C == P [T>] [E] [T<] cmp
|
||||
|
||||
[key value] query_key [left right] [K] P [T>] [E] [T<] cmp
|
||||
[key value] query_key [left right] [K] P [T>] [E] [T<] cmp
|
||||
|
||||
The predicate ``P``
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ An Example
|
|||
(... [3 4 ] 2 1 0 -- ... [1 2 ])
|
||||
|
||||
|
||||
Unification Works "in Reverse"
|
||||
Unification Works “in Reverse”
|
||||
------------------------------
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
|
|||
580
docs/Types.rst
580
docs/Types.rst
File diff suppressed because it is too large
Load Diff
|
|
@ -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 aren’t any complex datastructures, just ints, floats,
|
||||
strings, Symbols (strings that are names of functions) and sequences
|
||||
(aka lists, aka quoted literals, aka aggregates, etc...), but we can
|
||||
build
|
||||
(aka lists, aka quoted literals, aka aggregates, etc…), but we can build
|
||||
`trees <https://en.wikipedia.org/wiki/Tree_%28data_structure%29>`__ out
|
||||
of sequences.
|
||||
|
||||
|
|
@ -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
|
||||
Let’s use them to change 25 into 625. The first time a word is used I
|
||||
show the trace so you can see how it works. If we were going to use
|
||||
these a lot it would make sense to write Python versions for efficiency,
|
||||
but see below.
|
||||
|
|
@ -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 you’ll see that about half of it is the
|
||||
``dip`` and ``infra`` combinators de-quoting programs and “digging” into
|
||||
the subject datastructure. Instead of maintaining temporary results on
|
||||
the stack they are pushed into the pending expression (continuation).
|
||||
When ``sqr`` has run the rest of the pending expression rebuilds the
|
||||
|
|
@ -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 isn’t 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"
|
||||
It’s easy to read off (in reverse) the right sequence of “d” and “i”
|
||||
from the subject datastructure:
|
||||
|
||||
::
|
||||
|
||||
[ n [ n [ n n x ...
|
||||
i d i d i d d Bingo!
|
||||
[ n [ n [ n n x ...
|
||||
i d i d i d d Bingo!
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
We’re building a list of values so this is an “anamorphism”. (An
|
||||
anamorphism uses ``[]`` for ``c`` and ``swons`` for ``F``.)
|
||||
|
||||
::
|
||||
|
||||
scan == [P] [pop []] [[G] dupdip] [dip swons] genrec
|
||||
scan == [P] [pop []] [[G] dupdip] [dip swons] genrec
|
||||
|
||||
Convert to ``ifte``:
|
||||
|
||||
::
|
||||
|
||||
scan == [P] [pop []] [[G] dupdip [scan] dip swons] ifte
|
||||
scan == [P] [pop []] [[G] dupdip [scan] dip swons] ifte
|
||||
|
||||
On the recursive branch ``[G] dupdip`` doesn't cut it:
|
||||
On the recursive branch ``[G] dupdip`` doesn’t cut it:
|
||||
|
||||
::
|
||||
|
||||
[1 2 3] [G] dupdip [scan] dip swons
|
||||
[1 2 3] G [1 2 3] [scan] dip swons
|
||||
[1 2 3] [G] dupdip [scan] dip swons
|
||||
[1 2 3] G [1 2 3] [scan] dip swons
|
||||
|
||||
Use ``first``
|
||||
~~~~~~~~~~~~~
|
||||
|
|
@ -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:
|
||||
Let’s see what we’ve got so far:
|
||||
|
||||
::
|
||||
|
||||
scan == [P ] [pop []] [[G] dupdip first] [dip swons] genrec
|
||||
scan == [size 1 <=] [pop []] [[[F] infra] dupdip first] [dip swons] genrec
|
||||
scan == [P ] [pop []] [[G] dupdip first] [dip swons] genrec
|
||||
scan == [size 1 <=] [pop []] [[[F] infra] dupdip first] [dip swons] genrec
|
||||
|
||||
Handling the Last Term
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -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… Let’s 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 let’s just derive ``Lines``:
|
||||
|
||||
::
|
||||
|
||||
"abc\nefg\nhij" Lines
|
||||
---------------------------
|
||||
["abc" "efg" "hij"]
|
||||
"abc\nefg\nhij" Lines
|
||||
---------------------------
|
||||
["abc" "efg" "hij"]
|
||||
|
||||
Instead of ``P == [size 1 <=]`` we want ``["\n" in]``, and for the
|
||||
base-case of a string with no newlines in it we want to use ``unit``:
|
||||
|
||||
::
|
||||
|
||||
Lines == ["\n" in] [unit] [R0] [dip swons] genrec
|
||||
Lines == ["\n" in] [unit] [R0 [Lines] dip swons] ifte
|
||||
Lines == ["\n" in] [unit] [R0] [dip swons] genrec
|
||||
Lines == ["\n" in] [unit] [R0 [Lines] dip swons] ifte
|
||||
|
||||
Derive ``R0``:
|
||||
|
||||
::
|
||||
|
||||
"a \n b" R0 [Lines] dip swons
|
||||
"a \n b" split-at-newline swap [Lines] dip swons
|
||||
"a " " b" swap [Lines] dip swons
|
||||
" b" "a " [Lines] dip swons
|
||||
" b" Lines "a " swons
|
||||
[" b"] "a " swons
|
||||
["a " " b"]
|
||||
"a \n b" R0 [Lines] dip swons
|
||||
"a \n b" split-at-newline swap [Lines] dip swons
|
||||
"a " " b" swap [Lines] dip swons
|
||||
" b" "a " [Lines] dip swons
|
||||
" b" Lines "a " swons
|
||||
[" b"] "a " swons
|
||||
["a " " b"]
|
||||
|
||||
So:
|
||||
|
||||
::
|
||||
|
||||
R0 == split-at-newline swap
|
||||
R0 == split-at-newline swap
|
||||
|
||||
Lines == ["\n" in] [unit] [split-at-newline swap] [dip swons] genrec
|
||||
Lines == ["\n" in] [unit] [split-at-newline swap] [dip swons] genrec
|
||||
|
||||
Missing the Point?
|
||||
------------------
|
||||
|
|
@ -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 don’t have a “unit” we can fake it (the example is
|
||||
given of infinity for the ``min(a, b)`` function.) We can also use:
|
||||
|
||||
::
|
||||
|
||||
safe_step == [size 1 <=] [] [uncons [F] step] ifte
|
||||
safe_step == [size 1 <=] [] [uncons [F] step] ifte
|
||||
|
||||
Or:
|
||||
|
||||
::
|
||||
|
||||
safe_step == [pop size 1 <=] [pop] [[uncons] dip step] ifte
|
||||
safe_step == [pop size 1 <=] [pop] [[uncons] dip step] ifte
|
||||
|
||||
[a b c] [F] safe_step
|
||||
---------------------------
|
||||
a [b c] [F] step
|
||||
[a b c] [F] safe_step
|
||||
---------------------------
|
||||
a [b c] [F] step
|
||||
|
||||
To limit ``F`` to working on pairs of terms from its domain.
|
||||
|
||||
|
|
|
|||
|
|
@ -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 — 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>
|
||||
|
|
|
|||
|
|
@ -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 — 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">'''</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>
|
||||
|
|
|
|||
|
|
@ -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 — 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">'''</span>
|
||||
<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">print_function</span>
|
||||
<span class="kn">from</span> <span class="nn">builtins</span> <span class="kn">import</span> <span class="nb">map</span><span class="p">,</span> <span class="nb">object</span><span class="p">,</span> <span class="nb">range</span><span class="p">,</span> <span class="nb">zip</span>
|
||||
<span class="kn">from</span> <span class="nn">logging</span> <span class="kn">import</span> <span class="n">getLogger</span>
|
||||
<span class="kn">from</span> <span class="nn">__future__</span> <span class="k">import</span> <span class="n">print_function</span>
|
||||
<span class="kn">from</span> <span class="nn">builtins</span> <span class="k">import</span> <span class="nb">map</span><span class="p">,</span> <span class="nb">object</span><span class="p">,</span> <span class="nb">range</span><span class="p">,</span> <span class="nb">zip</span>
|
||||
<span class="kn">from</span> <span class="nn">logging</span> <span class="k">import</span> <span class="n">getLogger</span>
|
||||
|
||||
<span class="n">_log</span> <span class="o">=</span> <span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
|
||||
<span class="n">_log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s1">'Loading library.'</span><span class="p">)</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">inspect</span> <span class="kn">import</span> <span class="n">getdoc</span>
|
||||
<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">wraps</span>
|
||||
<span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">count</span>
|
||||
<span class="kn">from</span> <span class="nn">inspect</span> <span class="kn">import</span> <span class="n">getmembers</span><span class="p">,</span> <span class="n">isfunction</span>
|
||||
<span class="kn">from</span> <span class="nn">inspect</span> <span class="k">import</span> <span class="n">getdoc</span>
|
||||
<span class="kn">from</span> <span class="nn">functools</span> <span class="k">import</span> <span class="n">wraps</span>
|
||||
<span class="kn">from</span> <span class="nn">itertools</span> <span class="k">import</span> <span class="n">count</span>
|
||||
<span class="kn">from</span> <span class="nn">inspect</span> <span class="k">import</span> <span class="n">getmembers</span><span class="p">,</span> <span class="n">isfunction</span>
|
||||
<span class="kn">import</span> <span class="nn">operator</span><span class="o">,</span> <span class="nn">math</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">.parser</span> <span class="kn">import</span> <span class="n">text_to_expression</span><span class="p">,</span> <span class="n">Symbol</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="kn">import</span> <span class="n">expression_to_string</span><span class="p">,</span> <span class="n">list_to_stack</span><span class="p">,</span> <span class="n">iter_stack</span><span class="p">,</span> <span class="n">pick</span><span class="p">,</span> <span class="n">concat</span>
|
||||
<span class="kn">from</span> <span class="nn">.parser</span> <span class="k">import</span> <span class="n">text_to_expression</span><span class="p">,</span> <span class="n">Symbol</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="k">import</span> <span class="n">expression_to_string</span><span class="p">,</span> <span class="n">list_to_stack</span><span class="p">,</span> <span class="n">iter_stack</span><span class="p">,</span> <span class="n">pick</span><span class="p">,</span> <span class="n">concat</span>
|
||||
<span class="kn">import</span> <span class="nn">sys</span>
|
||||
<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="o">.</span><span class="n">major</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils.brutal_hackery</span> <span class="kn">import</span> <span class="n">rename_code_object</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils.brutal_hackery</span> <span class="k">import</span> <span class="n">rename_code_object</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">rename_code_object</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">_</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">f</span><span class="p">:</span> <span class="n">f</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">generated_library</span> <span class="k">as</span> <span class="n">genlib</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils.types</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils</span> <span class="k">import</span> <span class="n">generated_library</span> <span class="k">as</span> <span class="n">genlib</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils.types</span> <span class="k">import</span> <span class="p">(</span>
|
||||
<span class="n">compose</span><span class="p">,</span>
|
||||
<span class="n">ef</span><span class="p">,</span>
|
||||
<span class="n">stack_effect</span><span class="p">,</span>
|
||||
|
|
@ -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"># "sec": stack effect comment, like in Forth.</span>
|
||||
<span class="n">sec0</span> <span class="o">=</span> <span class="n">stack_effect</span><span class="p">(</span><span class="n">t1</span><span class="p">)()</span>
|
||||
<span class="n">sec1</span> <span class="o">=</span> <span class="n">stack_effect</span><span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="n">i1</span><span class="p">)(</span><span class="n">s1</span><span class="p">)</span>
|
||||
<span class="n">sec2</span> <span class="o">=</span> <span class="n">stack_effect</span><span class="p">(</span><span class="n">s0</span><span class="p">,</span> <span class="n">i1</span><span class="p">)(</span><span class="n">a1</span><span class="p">)</span>
|
||||
|
|
@ -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'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">'''</span><span class="se">\</span>
|
||||
<span class="s1">? == dup truthy</span>
|
||||
<span class="s1">*fraction == [uncons] dip uncons [swap] dip concat [*] infra [*] dip cons</span>
|
||||
<span class="s1">*fraction0 == concat [[swap] dip * [*] dip] infra</span>
|
||||
<span class="s1">anamorphism == [pop []] swap [dip swons] genrec</span>
|
||||
<span class="s1">average == [sum 1.0 *] [size] cleave /</span>
|
||||
<span class="s1">binary == nullary [popop] dip</span>
|
||||
<span class="s1">cleave == fork [popd] dip</span>
|
||||
<span class="s1">codireco == cons dip rest cons</span>
|
||||
<span class="s1">dinfrirst == dip infra first</span>
|
||||
<span class="s1">unstack == ? [uncons ?] loop pop</span>
|
||||
<span class="s1">down_to_zero == [0 >] [dup --] while</span>
|
||||
<span class="s1">dupdipd == dup dipd</span>
|
||||
<span class="s1">enstacken == stack [clear] dip</span>
|
||||
<span class="s1">flatten == [] swap [concat] step</span>
|
||||
<span class="s1">fork == [i] app2</span>
|
||||
<span class="s1">gcd == 1 [tuck modulus dup 0 >] loop pop</span>
|
||||
<span class="s1">ifte == [nullary not] dipd branch</span>
|
||||
<span class="s1">ii == [dip] dupdip i</span>
|
||||
<span class="s1">least_fraction == dup [gcd] infra [div] concat map</span>
|
||||
<span class="s1">make_generator == [codireco] ccons</span>
|
||||
<span class="s1">nullary == [stack] dinfrirst</span>
|
||||
<span class="s1">of == swap at</span>
|
||||
<span class="s1">pam == [i] map</span>
|
||||
<span class="s1">tailrec == [i] genrec</span>
|
||||
<span class="s1">product == 1 swap [*] step</span>
|
||||
<span class="s1">quoted == [unit] dip</span>
|
||||
<span class="s1">range == [0 <=] [1 - dup] anamorphism</span>
|
||||
<span class="s1">range_to_zero == unit [down_to_zero] infra</span>
|
||||
<span class="s1">run == [] swap infra</span>
|
||||
<span class="s1">size == 0 swap [pop ++] step</span>
|
||||
<span class="s1">sqr == dup mul</span>
|
||||
<span class="s1">step_zero == 0 roll> step</span>
|
||||
<span class="s1">swoncat == swap concat</span>
|
||||
<span class="s1">ternary == unary [popop] dip</span>
|
||||
<span class="s1">unary == nullary popd</span>
|
||||
<span class="s1">unquoted == [i] dip</span>
|
||||
<span class="s1">while == swap [nullary] cons dup dipd concat loop</span>
|
||||
<span class="s1">? dup truthy</span>
|
||||
<span class="s1">*fraction [uncons] dip uncons [swap] dip concat [*] infra [*] dip cons</span>
|
||||
<span class="s1">*fraction0 concat [[swap] dip * [*] dip] infra</span>
|
||||
<span class="s1">anamorphism [pop []] swap [dip swons] genrec</span>
|
||||
<span class="s1">average [sum 1.0 *] [size] cleave /</span>
|
||||
<span class="s1">binary nullary [popop] dip</span>
|
||||
<span class="s1">cleave fork [popd] dip</span>
|
||||
<span class="s1">codireco cons dip rest cons</span>
|
||||
<span class="s1">dinfrirst dip infra first</span>
|
||||
<span class="s1">unstack ? [uncons ?] loop pop</span>
|
||||
<span class="s1">down_to_zero [0 >] [dup --] while</span>
|
||||
<span class="s1">dupdipd dup dipd</span>
|
||||
<span class="s1">enstacken stack [clear] dip</span>
|
||||
<span class="s1">flatten [] swap [concat] step</span>
|
||||
<span class="s1">fork [i] app2</span>
|
||||
<span class="s1">gcd 1 [tuck modulus dup 0 >] loop pop</span>
|
||||
<span class="s1">ifte [nullary not] dipd branch</span>
|
||||
<span class="s1">ii [dip] dupdip i</span>
|
||||
<span class="s1">least_fraction dup [gcd] infra [div] concat map</span>
|
||||
<span class="s1">make_generator [codireco] ccons</span>
|
||||
<span class="s1">nullary [stack] dinfrirst</span>
|
||||
<span class="s1">of swap at</span>
|
||||
<span class="s1">pam [i] map</span>
|
||||
<span class="s1">tailrec [i] genrec</span>
|
||||
<span class="s1">product 1 swap [*] step</span>
|
||||
<span class="s1">quoted [unit] dip</span>
|
||||
<span class="s1">range [0 <=] [1 - dup] anamorphism</span>
|
||||
<span class="s1">range_to_zero unit [down_to_zero] infra</span>
|
||||
<span class="s1">run [] swap infra</span>
|
||||
<span class="s1">size 0 swap [pop ++] step</span>
|
||||
<span class="s1">sqr dup mul</span>
|
||||
<span class="s1">step_zero 0 roll> step</span>
|
||||
<span class="s1">swoncat swap concat</span>
|
||||
<span class="s1">ternary unary [popop] dip</span>
|
||||
<span class="s1">unary nullary popd</span>
|
||||
<span class="s1">unquoted [i] dip</span>
|
||||
<span class="s1">while swap [nullary] cons dup dipd concat loop</span>
|
||||
<span class="s1">'''</span>
|
||||
<span class="c1">#</span>
|
||||
<span class="c1">#</span>
|
||||
|
|
@ -389,14 +390,14 @@
|
|||
<span class="sd"> Provide implementation of defined functions, and some helper methods.</span>
|
||||
<span class="sd"> '''</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">body_text</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">body_text</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__name__</span> <span class="o">=</span> <span class="n">name</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">body</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="n">body_text</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_body</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">iter_stack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">body</span><span class="p">))</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="vm">__doc__</span> <span class="o">=</span> <span class="n">doc</span> <span class="ow">or</span> <span class="n">body_text</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_compiled</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
|
||||
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_compiled</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_compiled</span><span class="p">(</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">)</span> <span class="c1"># pylint: disable=E1102</span>
|
||||
<span class="n">expression</span> <span class="o">=</span> <span class="n">list_to_stack</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_body</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
|
||||
|
|
@ -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"> '''</span>
|
||||
<span class="n">name</span><span class="p">,</span> <span class="n">proper</span><span class="p">,</span> <span class="n">body_text</span> <span class="o">=</span> <span class="p">(</span><span class="n">n</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">defi</span><span class="o">.</span><span class="n">partition</span><span class="p">(</span><span class="s1">'=='</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">proper</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">'Definition </span><span class="si">%r</span><span class="s1"> failed'</span> <span class="o">%</span> <span class="p">(</span><span class="n">defi</span><span class="p">,))</span>
|
||||
<span class="k">return</span> <span class="n">class_</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">body_text</span><span class="p">)</span></div>
|
||||
<span class="k">return</span> <span class="n">class_</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">n</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">defi</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="mi">1</span><span class="p">)))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="DefinitionWrapper.add_definitions"><a class="viewcode-back" href="../../library.html#joy.library.DefinitionWrapper.add_definitions">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">add_definitions</span><span class="p">(</span><span class="n">class_</span><span class="p">,</span> <span class="n">defs</span><span class="p">,</span> <span class="n">dictionary</span><span class="p">):</span>
|
||||
|
|
@ -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">'=='</span> <span class="ow">in</span> <span class="n">line</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="p">(</span>
|
||||
<span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
|
||||
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">text</span><span class="o">.</span><span class="n">splitlines</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'#'</span><span class="p">)</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<span class="c1">#</span>
|
||||
|
|
@ -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">'choice'</span><span class="p">)</span>
|
||||
<span class="n">S_first</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'first'</span><span class="p">)</span>
|
||||
<span class="n">S_getitem</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'getitem'</span><span class="p">)</span>
|
||||
<span class="n">S_genrec</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'genrec'</span><span class="p">)</span>
|
||||
<span class="n">S_loop</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'loop'</span><span class="p">)</span>
|
||||
<span class="n">S_getitem</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'getitem'</span><span class="p">)</span>
|
||||
<span class="n">S_i</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'i'</span><span class="p">)</span>
|
||||
<span class="n">S_ifte</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'ifte'</span><span class="p">)</span>
|
||||
<span class="n">S_infra</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'infra'</span><span class="p">)</span>
|
||||
<span class="n">S_loop</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'loop'</span><span class="p">)</span>
|
||||
<span class="n">S_pop</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'pop'</span><span class="p">)</span>
|
||||
<span class="n">S_primrec</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'primrec'</span><span class="p">)</span>
|
||||
<span class="n">S_step</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'step'</span><span class="p">)</span>
|
||||
<span class="n">S_times</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'times'</span><span class="p">)</span>
|
||||
<span class="n">S_swaack</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'swaack'</span><span class="p">)</span>
|
||||
<span class="n">S_times</span> <span class="o">=</span> <span class="n">Symbol</span><span class="p">(</span><span class="s1">'times'</span><span class="p">)</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="i"><a class="viewcode-back" href="../../library.html#joy.library.i">[docs]</a><span class="nd">@inscribe</span>
|
||||
|
|
@ -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 "Recursion Theory and Joy" (j05cmp.html) by Manfred von Thun:</span>
|
||||
<span class="sd"> "The genrec combinator takes four program parameters in addition to</span>
|
||||
|
|
@ -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"> '''</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">'''</span>
|
||||
<span class="sd"> From the "Overview of the language JOY":</span>
|
||||
|
||||
<span class="sd"> > The primrec combinator expects two quoted programs in addition to a</span>
|
||||
<span class="sd"> data parameter. For an integer data parameter it works like this: If</span>
|
||||
<span class="sd"> the data parameter is zero, then the first quotation has to produce</span>
|
||||
<span class="sd"> the value to be returned. If the data parameter is positive then the</span>
|
||||
<span class="sd"> second has to combine the data parameter with the result of applying</span>
|
||||
<span class="sd"> the function to its predecessor.</span>
|
||||
|
||||
<span class="sd"> 5 [1] [*] primrec</span>
|
||||
|
||||
<span class="sd"> > Then primrec tests whether the top element on the stack (initially</span>
|
||||
<span class="sd"> the 5) is equal to zero. If it is, it pops it off and executes one of</span>
|
||||
<span class="sd"> the quotations, the [1] which leaves 1 on the stack as the result.</span>
|
||||
<span class="sd"> Otherwise it pushes a decremented copy of the top element and</span>
|
||||
<span class="sd"> recurses. On the way back from the recursion it uses the other</span>
|
||||
<span class="sd"> quotation, [*], to multiply what is now a factorial on top of the</span>
|
||||
<span class="sd"> stack by the second element on the stack.</span>
|
||||
|
||||
<span class="sd"> n [Base] [Recur] primrec</span>
|
||||
|
||||
<span class="sd"> 0 [Base] [Recur] primrec</span>
|
||||
<span class="sd"> ------------------------------</span>
|
||||
<span class="sd"> Base</span>
|
||||
|
||||
<span class="sd"> n [Base] [Recur] primrec</span>
|
||||
<span class="sd"> ------------------------------------------ n > 0</span>
|
||||
<span class="sd"> n (n-1) [Base] [Recur] primrec Recur</span>
|
||||
|
||||
<span class="sd"> '''</span>
|
||||
<span class="n">recur</span><span class="p">,</span> <span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">stack</span><span class="p">))</span> <span class="o">=</span> <span class="n">stack</span>
|
||||
<span class="k">if</span> <span class="n">n</span> <span class="o"><=</span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="n">expression</span> <span class="o">=</span> <span class="n">concat</span><span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">expression</span> <span class="o">=</span> <span class="n">S_primrec</span><span class="p">,</span> <span class="n">concat</span><span class="p">(</span><span class="n">recur</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
|
||||
<span class="n">stack</span> <span class="o">=</span> <span class="n">recur</span><span class="p">,</span> <span class="p">(</span><span class="n">base</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">stack</span><span class="p">)))</span>
|
||||
<span class="k">return</span> <span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">,</span> <span class="n">dictionary</span></div>
|
||||
|
||||
|
||||
<span class="c1">#def cleave(S, expression, dictionary):</span>
|
||||
<span class="c1"># '''</span>
|
||||
<span class="c1"># The cleave combinator expects two quotations, and below that an item X.</span>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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">'''</span>
|
||||
<span class="kn">from</span> <span class="nn">re</span> <span class="kn">import</span> <span class="n">Scanner</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="kn">import</span> <span class="n">list_to_stack</span>
|
||||
<span class="kn">from</span> <span class="nn">re</span> <span class="k">import</span> <span class="n">Scanner</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils.stack</span> <span class="k">import</span> <span class="n">list_to_stack</span>
|
||||
|
||||
|
||||
<span class="c1">#TODO: explain the details of float lits and strings.</span>
|
||||
<span class="n">FLOAT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'-?\d+\.\d*'</span>
|
||||
<span class="n">FLOAT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'-?\d+\.\d*(e(-|\+)\d+)+'</span>
|
||||
<span class="n">INT</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'-?\d+'</span>
|
||||
<span class="n">SYMBOL</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'[•\w!@$%^&*()_+<>?|\/;:`~,.=-]+'</span>
|
||||
<span class="n">BRACKETS</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">'\[|\]'</span>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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">'''</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"> '''</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"> '''</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">history</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">stack</span><span class="p">,</span> <span class="n">expression</span><span class="p">))</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">go</span><span class="p">())</span>
|
||||
|
||||
<div class="viewcode-block" id="TracePrinter.go"><a class="viewcode-back" href="../../../pretty.html#joy.utils.pretty_print.TracePrinter.go">[docs]</a> <span class="k">def</span> <span class="nf">go</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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 "Stack" Python class, instead we use the `cons list`_, a </span>
|
||||
<span class="sd">venerable two-tuple recursive sequence datastructure, where the</span>
|
||||
<span class="sd">empty tuple ``()`` is the empty stack and ``(head, rest)`` gives the recursive</span>
|
||||
<span class="sd">form of a stack with one or more items on it::</span>
|
||||
<span class="sd">empty tuple ``()`` is the empty stack and ``(head, rest)`` gives the</span>
|
||||
<span class="sd">recursive form of a stack with one or more items on it::</span>
|
||||
|
||||
<span class="sd"> stack := () | (item, stack)</span>
|
||||
|
||||
|
|
@ -106,7 +105,7 @@
|
|||
<span class="sd">'''</span>
|
||||
|
||||
|
||||
<span class="kn">from</span> <span class="nn">builtins</span> <span class="kn">import</span> <span class="nb">map</span>
|
||||
<span class="kn">from</span> <span class="nn">builtins</span> <span class="k">import</span> <span class="nb">map</span>
|
||||
<div class="viewcode-block" id="list_to_stack"><a class="viewcode-back" href="../../../stack.html#joy.utils.stack.list_to_stack">[docs]</a><span class="k">def</span> <span class="nf">list_to_stack</span><span class="p">(</span><span class="n">el</span><span class="p">,</span> <span class="n">stack</span><span class="o">=</span><span class="p">()):</span>
|
||||
<span class="sd">'''Convert a Python list (or other sequence) to a Joy stack::</span>
|
||||
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
@ -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
|
|
@ -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"> </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();
|
||||
});
|
||||
});
|
||||
|
|
@ -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 — 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>
|
||||
|
|
|
|||
|
|
@ -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 — 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. It’s 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. It’s 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. It’s 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>
|
||||
|
|
|
|||
|
|
@ -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 — 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
|
|
@ -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 — 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 Thun’s article <a class="reference external" href="http://www.kevinalbrecht.com/code/joy-mirror/j08cnt.html">Joy compared with other functional languages</a> he asks, “Could the language of categories be used for writing programs? Any lambda expression can be translated into a categorical expression, so the language of categories is expressively complete. But this does not make it a suitable language for writing programs. As it stands it is a very low-level language.”</p>
|
||||
<p>In <a class="reference external" href="http://conal.net/papers/compiling-to-categories/">Compiling to categories</a> Conal Elliott give a taste of what this might mean.</p>
|
||||
<blockquote>
|
||||
<div><p>It is well-known that the simply typed lambda-calculus is modeled by any cartesian closed category (CCC). This correspondence suggests giving typed functional programs a variety of interpretations, each corresponding to a different category. A convenient way to realize this idea is as a collection of meaning-preserving transformations added to an existing compiler, such as GHC for Haskell. This paper describes such an implementation and demonstrates its use for a variety of interpretations including hardware circuits, automatic differentiation, incremental computation, and interval analysis. Each such interpretation is a category easily defined in Haskell (outside of the compiler). The general technique appears to provide a compelling alternative to deeply embedded domain-specific languages.</p>
|
||||
</div></blockquote>
|
||||
<div>It is well-known that the simply typed lambda-calculus is modeled by any cartesian closed category (CCC). This correspondence suggests giving typed functional programs a variety of interpretations, each corresponding to a different category. A convenient way to realize this idea is as a collection of meaning-preserving transformations added to an existing compiler, such as GHC for Haskell. This paper describes such an implementation and demonstrates its use for a variety of interpretations including hardware circuits, automatic differentiation, incremental computation, and interval analysis. Each such interpretation is a category easily defined in Haskell (outside of the compiler). The general technique appears to provide a compelling alternative to deeply embedded domain-specific languages.</div></blockquote>
|
||||
<p>What he’s doing is translating lambda forms into a kind of “point-free” style that is very close to Joy code (although more verbose) and then showing how to instantiate that code over different categories to get several different kinds of program out of the same code.</p>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../index.html">Thun</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
|
||||
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
|
||||
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<div class="sphinxsidebarwrapper"><div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../index.html">Documentation overview</a><ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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>Brzozowski’s Derivatives of Regular Expressions<a class="headerlink" href="#brzozowski-s-derivatives-of-regular-expressions" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="section" id="brzozowskis-derivatives-of-regular-expressions">
|
||||
<h2>Brzozowski’s Derivatives of Regular Expressions<a class="headerlink" href="#brzozowskis-derivatives-of-regular-expressions" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Legend:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>∧ intersection
|
||||
∨ union
|
||||
|
|
@ -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">''</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">'0'</span><span class="p">}),</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'1'</span><span class="p">})</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">syms</span> <span class="o">=</span> <span class="n">O</span><span class="p">,</span> <span class="n">l</span> <span class="o">=</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'0'</span><span class="p">}),</span> <span class="nb">frozenset</span><span class="p">({</span><span class="s1">'1'</span><span class="p">})</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -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">'and cons * not or'</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="c1"># Tags are just strings.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">AND</span><span class="p">,</span> <span class="n">CONS</span><span class="p">,</span> <span class="n">KSTAR</span><span class="p">,</span> <span class="n">NOT</span><span class="p">,</span> <span class="n">OR</span> <span class="o">=</span> <span class="s1">'and cons * not or'</span><span class="o">.</span><span class="n">split</span><span class="p">()</span> <span class="c1"># Tags are just strings.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Because they are formed of <code class="docutils literal notranslate"><span class="pre">frozenset</span></code>, <code class="docutils literal notranslate"><span class="pre">tuple</span></code> and <code class="docutils literal notranslate"><span class="pre">str</span></code> objects
|
||||
|
|
@ -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">'''</span>
|
||||
<span class="sd"> Return a nice string repr for a regular expression datastructure.</span>
|
||||
<span class="sd"> '''</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">&</span> <span class="p">((</span><span class="o">.</span><span class="mi">01</span> <span class="o">|</span> <span class="mi">11</span><span class="o">*</span><span class="p">)</span><span class="s1">')</span>
|
||||
|
|
@ -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>Let’s get that auxiliary predicate function <code class="docutils literal notranslate"><span class="pre">δ</span></code> out of the way.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">nully</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">nully</span><span class="p">(</span><span class="n">R</span><span class="p">):</span>
|
||||
<span class="sd">'''</span>
|
||||
<span class="sd"> δ - Return λ if λ ⊆ R otherwise ϕ.</span>
|
||||
<span class="sd"> '''</span>
|
||||
|
|
@ -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>Let’s try it out…<a class="headerlink" href="#let-s-try-it-out" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="section" id="lets-try-it-out">
|
||||
<h2>Let’s try it out…<a class="headerlink" href="#lets-try-it-out" title="Permalink to this headline">¶</a></h2>
|
||||
<p>(FIXME: redo.)</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">o</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">o</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
|
||||
<span class="n">REs</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
||||
<span class="n">N</span> <span class="o">=</span> <span class="mi">5</span>
|
||||
<span class="n">names</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">product</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="n">N</span> <span class="o">*</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)])))</span>
|
||||
|
|
@ -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. each byte
|
||||
of the ASCII code. Or we can generalize this code. If you study the code
|
||||
above you’ll see that we never use the “set-ness” of the symbols <code class="docutils literal notranslate"><span class="pre">O</span></code>
|
||||
and <code class="docutils literal notranslate"><span class="pre">l</span></code>. The only time Python set operators (<code class="docutils literal notranslate"><span class="pre">&</span></code> and <code class="docutils literal notranslate"><span class="pre">|</span></code>) appear
|
||||
|
|
@ -499,8 +498,8 @@ machine transition table.</p>
|
|||
</pre></div>
|
||||
</div>
|
||||
<p>Says, “Three or more 1’s and not ending in 01 nor composed of all 1’s.”</p>
|
||||
<div class="figure align-default" id="id2">
|
||||
<img alt="omg.svg" src="notebooks/attachment:omg.svg" /><p class="caption"><span class="caption-text">omg.svg</span><a class="headerlink" href="#id2" title="Permalink to this image">¶</a></p>
|
||||
<div class="figure" id="id2">
|
||||
<img alt="omg.svg" src="notebooks/attachment:omg.svg" /><p class="caption"><span class="caption-text">omg.svg</span></p>
|
||||
</div>
|
||||
<p>Start at <code class="docutils literal notranslate"><span class="pre">a</span></code> and follow the transition arrows according to their
|
||||
labels. Accepting states have a double outline. (Graphic generated with
|
||||
|
|
@ -553,18 +552,18 @@ a --1--> ∂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">&</span></code>
|
||||
disappears once it has been matched.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">defaultdict</span>
|
||||
<span class="kn">from</span> <span class="nn">pprint</span> <span class="kn">import</span> <span class="n">pprint</span>
|
||||
<span class="kn">from</span> <span class="nn">string</span> <span class="kn">import</span> <span class="n">ascii_lowercase</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">collections</span> <span class="k">import</span> <span class="n">defaultdict</span>
|
||||
<span class="kn">from</span> <span class="nn">pprint</span> <span class="k">import</span> <span class="n">pprint</span>
|
||||
<span class="kn">from</span> <span class="nn">string</span> <span class="k">import</span> <span class="n">ascii_lowercase</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">d0</span><span class="p">,</span> <span class="n">d1</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">d0</span><span class="p">,</span> <span class="n">d1</span> <span class="o">=</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'0'</span><span class="p">),</span> <span class="n">D_compaction</span><span class="p">(</span><span class="s1">'1'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="explore">
|
||||
<h3><code class="docutils literal notranslate"><span class="pre">explore()</span></code><a class="headerlink" href="#explore" title="Permalink to this headline">¶</a></h3>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">explore</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">explore</span><span class="p">(</span><span class="n">re</span><span class="p">):</span>
|
||||
|
||||
<span class="c1"># Don't have more than 26 states...</span>
|
||||
<span class="n">names</span> <span class="o">=</span> <span class="n">defaultdict</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">ascii_lowercase</span><span class="p">)</span><span class="o">.</span><span class="n">next</span><span class="p">)</span>
|
||||
|
|
@ -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">'j'</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span> <span class="s1">'h'</span><span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">accepting</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">accepting</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="s1">'h'</span><span class="p">,</span> <span class="s1">'i'</span><span class="p">}</span>
|
||||
|
|
@ -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">'''</span><span class="se">\</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">_template</span> <span class="o">=</span> <span class="s1">'''</span><span class="se">\</span>
|
||||
<span class="s1">digraph finite_state_machine {</span>
|
||||
<span class="s1"> rankdir=LR;</span>
|
||||
<span class="s1"> size="8,5"</span>
|
||||
|
|
@ -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> isn’t.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">acceptable</span><span class="p">(</span><span class="n">input_</span><span class="p">):</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">acceptable</span><span class="p">(</span><span class="n">input_</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">trampoline</span><span class="p">(</span><span class="n">input_</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="p">{</span><span class="n">h</span><span class="p">,</span> <span class="n">i</span><span class="p">})</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">5</span><span class="p">):</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="o">**</span><span class="mi">5</span><span class="p">):</span>
|
||||
<span class="n">s</span> <span class="o">=</span> <span class="nb">bin</span><span class="p">(</span><span class="n">n</span><span class="p">)[</span><span class="mi">2</span><span class="p">:]</span>
|
||||
<span class="nb">print</span> <span class="s1">'</span><span class="si">%05s</span><span class="s1">'</span> <span class="o">%</span> <span class="n">s</span><span class="p">,</span> <span class="n">acceptable</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">∂RE</a><ul>
|
||||
<li><a class="reference internal" href="#brzozowskis-derivatives-of-regular-expressions">Brzozowski’s Derivatives of Regular Expressions</a></li>
|
||||
<li><a class="reference internal" href="#implementation">Implementation</a><ul>
|
||||
<li><a class="reference internal" href="#and"><code class="docutils literal notranslate"><span class="pre">ϕ</span></code> and <code class="docutils literal notranslate"><span class="pre">λ</span></code></a></li>
|
||||
<li><a class="reference internal" href="#two-letter-alphabet">Two-letter Alphabet</a></li>
|
||||
<li><a class="reference internal" href="#representing-regular-expressions">Representing Regular Expressions</a></li>
|
||||
<li><a class="reference internal" href="#string-representation-of-re-datastructures">String Representation of RE Datastructures</a></li>
|
||||
<li><a class="reference internal" href="#i"><code class="docutils literal notranslate"><span class="pre">I</span></code></a></li>
|
||||
<li><a class="reference internal" href="#id1"><code class="docutils literal notranslate"><span class="pre">(.111.)</span> <span class="pre">&</span> <span class="pre">(.01</span> <span class="pre">+</span> <span class="pre">11*)'</span></code></a></li>
|
||||
<li><a class="reference internal" href="#nully"><code class="docutils literal notranslate"><span class="pre">nully()</span></code></a></li>
|
||||
<li><a class="reference internal" href="#no-compaction">No “Compaction”</a></li>
|
||||
<li><a class="reference internal" href="#compaction-rules">Compaction Rules</a></li>
|
||||
<li><a class="reference internal" href="#memoizing">Memoizing</a></li>
|
||||
<li><a class="reference internal" href="#with-compaction">With “Compaction”</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#lets-try-it-out">Let’s try it out…</a></li>
|
||||
<li><a class="reference internal" href="#larger-alphabets">Larger Alphabets</a></li>
|
||||
<li><a class="reference internal" href="#state-machine">State Machine</a><ul>
|
||||
<li><a class="reference internal" href="#re-to-fsm">RE to FSM</a></li>
|
||||
<li><a class="reference internal" href="#explore"><code class="docutils literal notranslate"><span class="pre">explore()</span></code></a></li>
|
||||
<li><a class="reference internal" href="#generate-diagram">Generate Diagram</a></li>
|
||||
<li><a class="reference internal" href="#drive-a-fsm">Drive a FSM</a><ul>
|
||||
<li><a class="reference internal" href="#trampoline-function">Trampoline Function</a></li>
|
||||
<li><a class="reference internal" href="#stream-functions">Stream Functions</a></li>
|
||||
<li><a class="reference internal" href="#a-finite-state-machine">A Finite State Machine</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#reversing-the-derivatives-to-generate-matching-strings">Reversing the Derivatives to Generate Matching Strings</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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
|
|
@ -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 — 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 "warranty".
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type "sharing" for details.
|
||||
|
|
@ -58,7 +57,7 @@ Type "words" to see a list of all words, and "[<name>] help
|
|||
docs for a word.
|
||||
|
||||
|
||||
<-top
|
||||
<-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 <-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">'1 2 3 4 5'</span><span class="p">)</span> <span class="c1"># A simple sequence.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'1 2 3 4 5'</span><span class="p">)</span> <span class="c1"># A simple sequence.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="p">())))))</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[1 2 3] 4 5'</span><span class="p">)</span> <span class="c1"># Three items, the first is a list with three items</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[1 2 3] 4 5'</span><span class="p">)</span> <span class="c1"># Three items, the first is a list with three items</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">()))),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="p">())))</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'1 23 ["four" [-5.0] cons] 8888'</span><span class="p">)</span> <span class="c1"># A mixed bag. cons is</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'1 23 ["four" [-5.0] cons] 8888'</span><span class="p">)</span> <span class="c1"># A mixed bag. cons is</span>
|
||||
<span class="c1"># a Symbol, no lookup at</span>
|
||||
<span class="c1"># parse-time. Haiku docs.</span>
|
||||
</pre></div>
|
||||
|
|
@ -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">'four'</span><span class="p">,</span> <span class="p">((</span><span class="o">-</span><span class="mf">5.0</span><span class="p">,</span> <span class="p">()),</span> <span class="p">(</span><span class="n">cons</span><span class="p">,</span> <span class="p">()))),</span> <span class="p">(</span><span class="mi">8888</span><span class="p">,</span> <span class="p">()))))</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[][][][][]'</span><span class="p">)</span> <span class="c1"># Five empty lists.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[][][][][]'</span><span class="p">)</span> <span class="c1"># Five empty lists.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((),</span> <span class="p">((),</span> <span class="p">((),</span> <span class="p">((),</span> <span class="p">((),</span> <span class="p">())))))</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[[[[[]]]]]'</span><span class="p">)</span> <span class="c1"># Five nested lists.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">joy</span><span class="o">.</span><span class="n">parser</span><span class="o">.</span><span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[[[[[]]]]]'</span><span class="p">)</span> <span class="c1"># Five nested lists.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">((((((),</span> <span class="p">()),</span> <span class="p">()),</span> <span class="p">()),</span> <span class="p">()),</span> <span class="p">())</span>
|
||||
|
|
@ -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 <=] [1 - dup] anamorphism
|
||||
while == swap [nullary] cons dup dipd concat loop
|
||||
dudipd == dup dipd
|
||||
primrec == [i] genrec</pre>
|
||||
primrec == [i] genrec
|
||||
</pre>
|
||||
<p>Currently, there’s no function to add new definitions to the dictionary
|
||||
from “within” Joy code itself. Adding new definitions remains a
|
||||
meta-interpreter action. You have to do it yourself, in Python, and wash
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>Newton’s method — Thun 0.3.0 documentation</title>
|
||||
<link rel="stylesheet" href="../_static/alabaster.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
<script type="text/javascript" src="../_static/documentation_options.js"></script>
|
||||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Traversing Datastructures with Zippers" href="Zipper.html" />
|
||||
|
|
@ -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">Newton’s method</a><a class="headerlink" href="#newton-s-method" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="section" id="newtons-method">
|
||||
<h1><a class="reference external" href="https://en.wikipedia.org/wiki/Newton%27s_method">Newton’s method</a><a class="headerlink" href="#newtons-method" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Let’s use the Newton-Raphson method for finding the root of an equation
|
||||
to write a function that can compute the square root of a number.</p>
|
||||
<p>Cf. <a class="reference external" href="https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf">“Why Functional Programming Matters” by John
|
||||
Hughes</a></p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span><span class="p">,</span> <span class="n">define</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="section" id="a-generator-for-approximations">
|
||||
|
|
@ -91,10 +90,10 @@ function we’re 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">'gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'gsra == 1 swap [over / + 2 /] cons [dup] swoncat make_generator'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="n">dup</span> <span class="mi">23</span> <span class="n">over</span> <span class="o">/</span> <span class="o">+</span> <span class="mi">2</span> <span class="o">/</span><span class="p">]</span> <span class="n">codireco</span><span class="p">]</span>
|
||||
|
|
@ -102,7 +101,7 @@ function we’re writing. If we let 1 be the initial approximation:</p>
|
|||
</div>
|
||||
<p>Let’s drive the generator a few time (with the <code class="docutils literal notranslate"><span class="pre">x</span></code> combinator) and
|
||||
square the approximation to see how well it works…</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra 6 [x popd] times first sqr'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 gsra 6 [x popd] times first sqr'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">23.0000000001585</span>
|
||||
|
|
@ -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"><=</span><span class="n">ε</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_P == [first - abs] dip <='</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_P == [first - abs] dip <='</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -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">'_within_B == roll< popop first'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_B == roll< popop first'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -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">'_within_R == [popd x] dip'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'_within_R == [popd x] dip'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -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">'within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'within == x 0.000000001 [_within_P] [_within_B] [_within_R] primrec'</span><span class="p">)</span>
|
||||
<span class="n">define</span><span class="p">(</span><span class="s1">'sqrt == gsra within'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Try it out…</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'36 sqrt'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'36 sqrt'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">6.0</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqrt'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'23 sqrt'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Check it.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span><span class="o">**</span><span class="mi">2</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">4.795831523312719</span><span class="o">**</span><span class="mi">2</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mf">22.999999999999996</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">sqrt</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">math</span> <span class="k">import</span> <span class="n">sqrt</span>
|
||||
|
||||
<span class="n">sqrt</span><span class="p">(</span><span class="mi">23</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
|
@ -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="#">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Newton’s method</a><ul>
|
||||
<li><a class="reference internal" href="#a-generator-for-approximations">A Generator for Approximations</a><ul>
|
||||
<li><a class="reference internal" href="#a-function-to-compute-the-next-approximation">A Function to Compute the Next Approximation</a></li>
|
||||
<li><a class="reference internal" href="#make-it-into-a-generator">Make it into a Generator</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#finding-consecutive-approximations-within-a-tolerance">Finding Consecutive Approximations within a Tolerance</a><ul>
|
||||
<li><a class="reference internal" href="#predicate">Predicate</a></li>
|
||||
<li><a class="reference internal" href="#base-case">Base-Case</a></li>
|
||||
<li><a class="reference internal" href="#recur">Recur</a></li>
|
||||
<li><a class="reference internal" href="#setting-up">Setting up</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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 doesn’t need to change.</p></li>
|
||||
<li>Joy doesn’t need to change.</li>
|
||||
</ol>
|
||||
<blockquote>
|
||||
<div><ol class="upperalpha simple">
|
||||
<li><p>The interpreter doesn’t need to change, <code class="docutils literal notranslate"><span class="pre">viewer</span></code> function can customize mainloop. Or use a sub-interpreter (Joy in Joy.) The base interpreter remains static.</p></li>
|
||||
<li><p>Once a function has been named and defined <em>never change that name</em>. It’s just not allowed. If you need to change a function <code class="docutils literal notranslate"><span class="pre">foo</span></code> you have to call it <code class="docutils literal notranslate"><span class="pre">foo_II</span></code> or something. Once a function (name mapped to behavior) is released to the public <em>that’s it</em>, it’s done.</p></li>
|
||||
<li><p>The language evolves by adding new definitions and refactoring, always choosing new names for new functions.</p></li>
|
||||
<li>The interpreter doesn’t need to change, <code class="docutils literal notranslate"><span class="pre">viewer</span></code> function can customize mainloop. Or use a sub-interpreter (Joy in Joy.) The base interpreter remains static.</li>
|
||||
<li>Once a function has been named and defined <em>never change that name</em>. It’s just not allowed. If you need to change a function <code class="docutils literal notranslate"><span class="pre">foo</span></code> you have to call it <code class="docutils literal notranslate"><span class="pre">foo_II</span></code> or something. Once a function (name mapped to behavior) is released to the public <em>that’s it</em>, it’s done.</li>
|
||||
<li>The language evolves by adding new definitions and refactoring, always choosing new names for new functions.</li>
|
||||
</ol>
|
||||
</div></blockquote>
|
||||
<ol class="arabic simple" start="2">
|
||||
<li><p>Following <a class="reference external" href="https://semver.org">Semantic Versioning</a> there will never be a version 2.0.</p></li>
|
||||
<li>Following <a class="reference external" href="https://semver.org">Semantic Versioning</a> there will never be a version 2.0.</li>
|
||||
</ol>
|
||||
<blockquote>
|
||||
<div><ol class="upperalpha simple">
|
||||
<li><p><a class="reference external" href="https://semver.org/#spec-item-8">Major version must be incremented if any backwards incompatible changes are introduced to the public API.</a></p></li>
|
||||
<li><p>We never implement any backwards incompatible changes, so…</p></li>
|
||||
<li><p>We could see e.g. Thun version 1.273.3!</p></li>
|
||||
<li><a class="reference external" href="https://semver.org/#spec-item-8">Major version must be incremented if any backwards incompatible changes are introduced to the public API.</a></li>
|
||||
<li>We never implement any backwards incompatible changes, so…</li>
|
||||
<li>We could see e.g. Thun version 1.273.3!</li>
|
||||
</ol>
|
||||
</div></blockquote>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../index.html">Thun</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="Intro.html">Thun: Joy in Python</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../joy.html">Joy Interpreter</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../stack.html">Stack or Quote or Sequence or List…</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../parser.html">Parsing Text into Joy Expressions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../pretty.html">Tracing Joy Execution</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../library.html">Function Reference</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../lib.html">Functions Grouped by, er, Function with Examples</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../types.html">Type Inference of Joy Expressions</a></li>
|
||||
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Essays about Programming in Joy</a><ul class="current">
|
||||
<li class="toctree-l2"><a class="reference internal" href="Developing.html">Developing a Program in Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Quadratic.html">Quadratic formula</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Replacing.html">Replacing Functions in the Dictionary</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Recursion_Combinators.html">Recursion Combinators</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Ordered_Binary_Trees.html">Treating Trees I: Ordered Binary Trees</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Treestep.html">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Generator_Programs.html">Using <code class="docutils literal notranslate"><span class="pre">x</span></code> to Generate Values</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Newton-Raphson.html">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<div class="sphinxsidebarwrapper"><div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../index.html">Documentation overview</a><ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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">'Tree-new == swap [[] []] cons cons'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-new == swap [[] []] cons cons'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'"v" "k" Tree-new'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'"v" "k" Tree-new'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'k'</span> <span class="s1">'v'</span> <span class="p">[]</span> <span class="p">[]]</span>
|
||||
|
|
@ -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">></span> <span class="n">pop</span> <span class="n">first</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == pop roll> pop first'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == pop roll> pop first'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_key" 23 [] []] 17 "new_key" ["..."] P'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_key" 23 [] []] 17 "new_key" ["..."] P'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'new_key'</span> <span class="s1">'old_key'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="if-the-key-we-re-adding-is-greater-than-the-node-s-key">
|
||||
<h4>If the key we’re adding is greater than the node’s key.<a class="headerlink" href="#if-the-key-we-re-adding-is-greater-than-the-node-s-key" title="Permalink to this headline">¶</a></h4>
|
||||
<div class="section" id="if-the-key-were-adding-is-greater-than-the-nodes-key">
|
||||
<h4>If the key we’re adding is greater than the node’s key.<a class="headerlink" href="#if-the-key-were-adding-is-greater-than-the-nodes-key" title="Permalink to this headline">¶</a></h4>
|
||||
<p>Here the parentheses are meant to signify that the expression is not
|
||||
literal, the code in the parentheses is meant to have been evaluated:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="p">[</span><span class="n">key_n</span> <span class="n">value_n</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="n">value</span> <span class="n">key</span> <span class="p">[</span><span class="n">Tree</span><span class="o">-</span><span class="n">add</span><span class="p">]</span> <span class="n">T</span>
|
||||
|
|
@ -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">'T == cons cons [dipdd] cons infra'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'T == cons cons [dipdd] cons infra'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] T'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] T'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'old_k'</span> <span class="s1">'old_value'</span> <span class="s1">'left'</span> <span class="s1">'Tree-add'</span> <span class="s1">'new_key'</span> <span class="s1">'new_value'</span> <span class="s1">'right'</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="if-the-key-we-re-adding-is-less-than-the-node-s-key">
|
||||
<h4>If the key we’re adding is less than the node’s key.<a class="headerlink" href="#if-the-key-we-re-adding-is-less-than-the-node-s-key" title="Permalink to this headline">¶</a></h4>
|
||||
<div class="section" id="if-the-key-were-adding-is-less-than-the-nodes-key">
|
||||
<h4>If the key we’re adding is less than the node’s key.<a class="headerlink" href="#if-the-key-were-adding-is-less-than-the-nodes-key" title="Permalink to this headline">¶</a></h4>
|
||||
<p>This is very very similar to the above:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="n">key_n</span> <span class="n">value_n</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="n">value</span> <span class="n">key</span> <span class="p">[</span><span class="n">Tree</span><span class="o">-</span><span class="n">add</span><span class="p">]</span> <span class="n">E</span>
|
||||
<span class="p">[</span><span class="n">key_n</span> <span class="n">value_n</span> <span class="n">left</span> <span class="n">right</span><span class="p">]</span> <span class="n">value</span> <span class="n">key</span> <span class="p">[</span><span class="n">Tree</span><span class="o">-</span><span class="n">add</span><span class="p">]</span> <span class="p">[</span><span class="n">P</span> <span class="o"><</span><span class="p">]</span> <span class="p">[</span><span class="n">Te</span><span class="p">]</span> <span class="p">[</span><span class="n">Ee</span><span class="p">]</span> <span class="n">ifte</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'E == [P <] [Te] [Ee] ifte'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'E == [P <] [Te] [Ee] ifte'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>In this case <code class="docutils literal notranslate"><span class="pre">Te</span></code> works that same as <code class="docutils literal notranslate"><span class="pre">T</span></code> but on the left child tree
|
||||
|
|
@ -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">'Te == cons cons [dipd] cons infra'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Te == cons cons [dipd] cons infra'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] Te'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] Te'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'old_k'</span> <span class="s1">'old_value'</span> <span class="s1">'Tree-add'</span> <span class="s1">'new_key'</span> <span class="s1">'new_value'</span> <span class="s1">'left'</span> <span class="s1">'right'</span><span class="p">]</span>
|
||||
|
|
@ -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">'Ee == pop swap roll< rest rest cons cons'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Ee == pop swap roll< rest rest cons cons'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["k" "old_value" "left" "right"] "new_value" "k" ["Tree-add"] Ee'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["k" "old_value" "left" "right"] "new_value" "k" ["Tree-add"] Ee'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'k'</span> <span class="s1">'new_value'</span> <span class="s1">'left'</span> <span class="s1">'right'</span><span class="p">]</span>
|
||||
|
|
@ -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">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="examples">
|
||||
<h3>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h3>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Initial</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Initial</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Greater than</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Greater than</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "a" Tree-add'</span><span class="p">)</span> <span class="c1"># Less than</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "a" Tree-add'</span><span class="p">)</span> <span class="c1"># Less than</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Equal to</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["b" 23 [] []] 88 "b" Tree-add'</span><span class="p">)</span> <span class="c1"># Equal to</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Series.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Series.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
|
||||
|
|
@ -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">"1 0 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 0 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'G'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"1 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'E'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"0 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"0 1 ['G'] ['E'] ['L'] cmp"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'L'</span>
|
||||
|
|
@ -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">'P == over [popop popop first] nullary'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'P == over [popop popop first] nullary'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Using <code class="docutils literal notranslate"><span class="pre">cmp</span></code> to simplify <cite>our code above at
|
||||
|
|
@ -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">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Still works.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add'</span><span class="p">)</span> <span class="c1"># Still works.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">23</span> <span class="p">[</span><span class="s1">'a'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
|
||||
|
|
@ -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"><</span> <span class="p">[</span><span class="n">dupdip</span> <span class="n">rest</span> <span class="n">rest</span><span class="p">]</span> <span class="n">cons</span> <span class="p">[</span><span class="n">step</span><span class="p">]</span> <span class="n">genrec</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="id1">
|
||||
<h3>Examples<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h3>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [foo] Tree-iter'</span><span class="p">)</span> <span class="c1"># It doesn't matter what F is as it won't be used.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [foo] Tree-iter'</span><span class="p">)</span> <span class="c1"># It doesn't matter what F is as it won't be used.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter"</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'b'</span> <span class="s1">'a'</span> <span class="s1">'c'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter"</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter"</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span> <span class="mi">88</span> <span class="mi">44</span>
|
||||
|
|
@ -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. It’s set-like in that duplicate items added
|
||||
to e.g. 0 and ignoring them. It’s set-like in that duplicate items added
|
||||
to it will only occur once within it, and we can query it in
|
||||
<cite>:math:`O(log_2 N)</cite> <<a class="reference external" href="https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2">https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2</a>>`__
|
||||
time.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'to_set == [] swap [0 swap Tree-add] step'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'to_set == [] swap [0 swap Tree-add] step'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
|
||||
|
|
@ -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">'unique == [to_set [first] Tree-iter] cons run'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'unique == [to_set [first] Tree-iter] cons run'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique'</span><span class="p">)</span> <span class="c1"># Filter duplicate items.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique'</span><span class="p">)</span> <span class="c1"># Filter duplicate items.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">7</span> <span class="mi">6</span> <span class="mi">8</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">9</span> <span class="mi">2</span> <span class="mi">3</span><span class="p">]</span>
|
||||
|
|
@ -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('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')</span>
|
||||
|
||||
|
||||
<span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
|
||||
|
|
@ -695,7 +694,7 @@ right side:</p>
|
|||
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span>
|
||||
|
|
@ -835,7 +834,7 @@ because there’s 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">></span><span class="p">]</span> <span class="p">[</span><span class="n">E</span><span class="p">]</span> <span class="p">[</span><span class="n">T</span><span class="o"><</span><span class="p">]</span> <span class="nb">cmp</span><span class="p">]</span> <span class="n">genrec</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="c1"># I don't want to deal with name conflicts with the above so I'm inlining everything here.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># I don't want to deal with name conflicts with the above so I'm inlining everything here.</span>
|
||||
<span class="c1"># The original Joy system has "hide" which is a meta-command which allows you to use named</span>
|
||||
<span class="c1"># definitions that are only in scope for a given definition. I don't want to implement</span>
|
||||
<span class="c1"># that (yet) so...</span>
|
||||
|
|
@ -852,19 +851,19 @@ because there’s no value to discard.</p>
|
|||
<span class="s1">'''</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'mike not in tree'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "gary" [popop "err"] Tree-get'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'["gary" 23 [] []] "gary" [popop "err"] Tree-get'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
|
||||
|
||||
<span class="s1"> [] [[0 'a'] [1 'b'] [2 'c']] [i Tree-add] step</span>
|
||||
|
||||
|
|
@ -876,7 +875,7 @@ because there’s 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">'''</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span>
|
||||
|
||||
<span class="s1"> [] [[0 'a'] [1 'b'] [2 'c']] [i Tree-add] step</span>
|
||||
|
||||
|
|
@ -1175,7 +1174,7 @@ E == [
|
|||
</div>
|
||||
<p>By the standards of the code I’ve written so far, this is a <em>huge</em> Joy
|
||||
program.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
|
||||
<span class="s1">first_two == uncons uncons pop</span>
|
||||
<span class="s1">fourth == rest rest rest first</span>
|
||||
<span class="s1">?fourth == [] [fourth] [] ifte</span>
|
||||
|
|
@ -1193,43 +1192,43 @@ program.</p>
|
|||
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete "</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete "</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'a'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete "</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete "</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'a'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete "</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete "</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete "</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete "</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'a'</span> <span class="mi">23</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'b'</span> <span class="mi">88</span> <span class="p">[]</span> <span class="p">[</span><span class="s1">'c'</span> <span class="mi">44</span> <span class="p">[]</span> <span class="p">[]]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete "</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete "</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete "</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s2">"[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete "</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">1</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span> <span class="p">[]</span> <span class="p">[]]]]</span>
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Treating Trees I: Ordered Binary Trees</a><ul>
|
||||
<li><a class="reference internal" href="#adding-nodes-to-the-tree">Adding Nodes to the Tree</a><ul>
|
||||
<li><a class="reference internal" href="#adding-to-an-empty-node">Adding to an empty node.</a><ul>
|
||||
<li><a class="reference internal" href="#tree-new"><code class="docutils literal notranslate"><span class="pre">Tree-new</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#adding-to-a-non-empty-node">Adding to a non-empty node.</a><ul>
|
||||
<li><a class="reference internal" href="#a-predicate-to-compare-keys">A predicate to compare keys.</a></li>
|
||||
<li><a class="reference internal" href="#if-the-key-were-adding-is-greater-than-the-nodes-key">If the key we’re adding is greater than the node’s key.</a></li>
|
||||
<li><a class="reference internal" href="#if-the-key-were-adding-is-less-than-the-nodes-key">If the key we’re adding is less than the node’s key.</a></li>
|
||||
<li><a class="reference internal" href="#else-the-keys-must-be-equal">Else the keys must be equal.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#now-we-can-define-tree-add">Now we can define <code class="docutils literal notranslate"><span class="pre">Tree-add</span></code></a></li>
|
||||
<li><a class="reference internal" href="#examples">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#interlude-cmp-combinator">Interlude: <code class="docutils literal notranslate"><span class="pre">cmp</span></code> combinator</a><ul>
|
||||
<li><a class="reference internal" href="#redefine-tree-add">Redefine <code class="docutils literal notranslate"><span class="pre">Tree-add</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#a-function-to-traverse-this-structure">A Function to Traverse this Structure</a><ul>
|
||||
<li><a class="reference internal" href="#base-case">Base case <code class="docutils literal notranslate"><span class="pre">[]</span></code></a></li>
|
||||
<li><a class="reference internal" href="#node-case-key-value-left-right">Node case <code class="docutils literal notranslate"><span class="pre">[key</span> <span class="pre">value</span> <span class="pre">left</span> <span class="pre">right]</span></code></a><ul>
|
||||
<li><a class="reference internal" href="#processing-the-current-node">Processing the current node.</a></li>
|
||||
<li><a class="reference internal" href="#recur">Recur</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#putting-it-together">Putting it together</a></li>
|
||||
<li><a class="reference internal" href="#parameterizing-the-f-per-node-processing-function">Parameterizing the <code class="docutils literal notranslate"><span class="pre">F</span></code> per-node processing function.</a></li>
|
||||
<li><a class="reference internal" href="#tree-iter"><code class="docutils literal notranslate"><span class="pre">Tree-iter</span></code></a></li>
|
||||
<li><a class="reference internal" href="#id1">Examples</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#interlude-a-set-like-datastructure">Interlude: A Set-like Datastructure</a></li>
|
||||
<li><a class="reference internal" href="#a-version-of-tree-iter-that-does-in-order-traversal">A Version of <code class="docutils literal notranslate"><span class="pre">Tree-iter</span></code> that does In-Order Traversal</a><ul>
|
||||
<li><a class="reference internal" href="#process-the-left-child">Process the left child.</a></li>
|
||||
<li><a class="reference internal" href="#process-the-current-node">Process the current node.</a></li>
|
||||
<li><a class="reference internal" href="#process-the-right-child">Process the right child.</a></li>
|
||||
<li><a class="reference internal" href="#defining-tree-iter-order">Defining <code class="docutils literal notranslate"><span class="pre">Tree-iter-order</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#getting-values-by-key">Getting values by key</a><ul>
|
||||
<li><a class="reference internal" href="#the-base-case">The base case <code class="docutils literal notranslate"><span class="pre">[]</span></code></a></li>
|
||||
<li><a class="reference internal" href="#id2">Node case <code class="docutils literal notranslate"><span class="pre">[key</span> <span class="pre">value</span> <span class="pre">left</span> <span class="pre">right]</span></code></a><ul>
|
||||
<li><a class="reference internal" href="#predicate">Predicate</a></li>
|
||||
<li><a class="reference internal" href="#branches">Branches</a></li>
|
||||
<li><a class="reference internal" href="#greater-than-and-less-than">Greater than and less than</a></li>
|
||||
<li><a class="reference internal" href="#equal-keys">Equal keys</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#tree-get"><code class="docutils literal notranslate"><span class="pre">Tree-get</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#tree-delete">Tree-delete</a><ul>
|
||||
<li><a class="reference internal" href="#id3">Base case</a></li>
|
||||
<li><a class="reference internal" href="#id4">Recur</a></li>
|
||||
<li><a class="reference internal" href="#compare-keys">Compare Keys</a></li>
|
||||
<li><a class="reference internal" href="#greater-than-case-and-less-than-case">Greater than case and less than case</a></li>
|
||||
<li><a class="reference internal" href="#the-else-case">The else case</a><ul>
|
||||
<li><a class="reference internal" href="#one-or-more-child-nodes-are">One or more child nodes are <code class="docutils literal notranslate"><span class="pre">[]</span></code></a></li>
|
||||
<li><a class="reference internal" href="#both-child-nodes-are-non-empty">Both child nodes are non-empty.</a></li>
|
||||
<li><a class="reference internal" href="#we-have-to-we-find-the-highest-right-most-node-in-our-lower-left-sub-tree">We have to we find the highest (right-most) node in our lower (left) sub-tree:</a></li>
|
||||
<li><a class="reference internal" href="#found-right-most-node-in-our-left-sub-tree">Found right-most node in our left sub-tree</a></li>
|
||||
<li><a class="reference internal" href="#replace-current-node-key-and-value-recursively-delete-rightmost">Replace current node key and value, recursively delete rightmost</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#refactoring">Refactoring</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#appendix-the-source-code">Appendix: The source code.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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 it’s the definition of the <code class="docutils literal notranslate"><span class="pre">quadratic</span></code> function:</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Let’s try it out:</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 1 1 quadratic'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'3 1 1 quadratic'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="mf">0.3819660112501051</span> <span class="o">-</span><span class="mf">2.618033988749895</span>
|
||||
|
|
@ -113,7 +112,7 @@ the right and say it’s 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">'-5 1 4 quadratic'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'-5 1 4 quadratic'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="o">-</span><span class="mi">5</span> <span class="mi">1</span> <span class="mi">4</span> <span class="n">quadratic</span>
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Quadratic formula</a><ul>
|
||||
<li><a class="reference internal" href="#write-a-straightforward-program-with-variable-names">Write a straightforward program with variable names.</a><ul>
|
||||
<li><a class="reference internal" href="#b"><code class="docutils literal notranslate"><span class="pre">-b</span></code></a></li>
|
||||
<li><a class="reference internal" href="#sqrt-b-2-4-a-c"><code class="docutils literal notranslate"><span class="pre">sqrt(b^2</span> <span class="pre">-</span> <span class="pre">4</span> <span class="pre">*</span> <span class="pre">a</span> <span class="pre">*</span> <span class="pre">c)</span></code></a></li>
|
||||
<li><a class="reference internal" href="#a"><code class="docutils literal notranslate"><span class="pre">/2a</span></code></a></li>
|
||||
<li><a class="reference internal" href="#id1"><code class="docutils literal notranslate"><span class="pre">±</span></code></a></li>
|
||||
<li><a class="reference internal" href="#putting-them-together">Putting Them Together</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#derive-a-definition">Derive a definition.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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">-></span> <span class="pre">C</span></code> that converts a value of type
|
||||
<code class="docutils literal notranslate"><span class="pre">A</span></code> into a value of type <code class="docutils literal notranslate"><span class="pre">C</span></code> by means of:</p>
|
||||
<ul class="simple">
|
||||
<li><p>A generator <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-></span> <span class="pre">(B,</span> <span class="pre">A)</span></code></p></li>
|
||||
<li><p>A combiner <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">::</span> <span class="pre">(B,</span> <span class="pre">C)</span> <span class="pre">-></span> <span class="pre">C</span></code></p></li>
|
||||
<li><p>A predicate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-></span> <span class="pre">Bool</span></code> to detect the base case</p></li>
|
||||
<li><p>A base case value <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">::</span> <span class="pre">C</span></code></p></li>
|
||||
<li><p>Recursive calls (zero or more); it has a “call stack in the form of a
|
||||
cons list”.</p></li>
|
||||
<li>A generator <code class="docutils literal notranslate"><span class="pre">G</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-></span> <span class="pre">(B,</span> <span class="pre">A)</span></code></li>
|
||||
<li>A combiner <code class="docutils literal notranslate"><span class="pre">F</span> <span class="pre">::</span> <span class="pre">(B,</span> <span class="pre">C)</span> <span class="pre">-></span> <span class="pre">C</span></code></li>
|
||||
<li>A predicate <code class="docutils literal notranslate"><span class="pre">P</span> <span class="pre">::</span> <span class="pre">A</span> <span class="pre">-></span> <span class="pre">Bool</span></code> to detect the base case</li>
|
||||
<li>A base case value <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">::</span> <span class="pre">C</span></code></li>
|
||||
<li>Recursive calls (zero or more); it has a “call stack in the form of a
|
||||
cons list”.</li>
|
||||
</ul>
|
||||
<p>It may be helpful to see this function implemented in imperative Python
|
||||
code.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hylomorphism</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">hylomorphism</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">F</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">G</span><span class="p">):</span>
|
||||
<span class="sd">'''Return a hylomorphism function H.'''</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">H</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
|
||||
|
|
@ -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">'hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="section" id="example-finding-triangular-numbers">
|
||||
|
|
@ -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"><=]</span></code></p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">c</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code></p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">[G]</span></code> is <code class="docutils literal notranslate"><span class="pre">[--</span> <span class="pre">dup]</span></code></p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">[F]</span></code> is <code class="docutils literal notranslate"><span class="pre">[+]</span></code></p></li>
|
||||
<li><code class="docutils literal notranslate"><span class="pre">[P]</span></code> is <code class="docutils literal notranslate"><span class="pre">[1</span> <span class="pre"><=]</span></code></li>
|
||||
<li><code class="docutils literal notranslate"><span class="pre">c</span></code> is <code class="docutils literal notranslate"><span class="pre">0</span></code></li>
|
||||
<li><code class="docutils literal notranslate"><span class="pre">[G]</span></code> is <code class="docutils literal notranslate"><span class="pre">[--</span> <span class="pre">dup]</span></code></li>
|
||||
<li><code class="docutils literal notranslate"><span class="pre">[F]</span></code> is <code class="docutils literal notranslate"><span class="pre">[+]</span></code></li>
|
||||
</ul>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Let’s try it:</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 triangular_number'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 triangular_number'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">10</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 1 2 3 4 5 6] [triangular_number] map'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[0 1 2 3 4 5 6] [triangular_number] map'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">3</span> <span class="mi">6</span> <span class="mi">10</span> <span class="mi">15</span><span class="p">]</span>
|
||||
|
|
@ -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. 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"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range == [0 <=] [] [-- dup] [swons] hylomorphism'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range == [0 <=] [] [-- dup] [swons] hylomorphism'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span><span class="p">]</span>
|
||||
|
|
@ -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"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[</span><span class="o">--</span> <span class="n">dup</span> <span class="p">[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">primrec</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range_reverse'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 range_reverse'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span>
|
||||
|
|
@ -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"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span> <span class="p">[]]</span> <span class="p">[[</span><span class="o">--</span><span class="p">]</span> <span class="n">dupdip</span><span class="p">]</span> <span class="p">[</span><span class="n">dip</span> <span class="n">swons</span><span class="p">]</span> <span class="n">genrec</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">5</span> <span class="mi">4</span> <span class="mi">3</span> <span class="mi">2</span> <span class="mi">1</span><span class="p">]</span>
|
||||
|
|
@ -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"><=</span><span class="p">]</span> <span class="p">[</span><span class="n">pop</span><span class="p">]</span> <span class="p">[[</span><span class="n">swons</span><span class="p">]</span> <span class="n">dupdip</span> <span class="o">--</span><span class="p">]</span> <span class="n">primrec</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger_reverse'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 ranger_reverse'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span><span class="p">]</span>
|
||||
|
|
@ -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">'swuncons == uncons swap'</span><span class="p">)</span> <span class="c1"># Awkward name.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'swuncons == uncons swap'</span><span class="p">)</span> <span class="c1"># Awkward name.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>An example of a catamorphism is the sum function.</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="nb">sum</span> <span class="o">==</span> <span class="p">[</span><span class="ow">not</span><span class="p">]</span> <span class="mi">0</span> <span class="p">[</span><span class="n">swuncons</span><span class="p">]</span> <span class="p">[</span><span class="o">+</span><span class="p">]</span> <span class="n">hylomorphism</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == [not] 0 [swuncons] [+] hylomorphism'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == [not] 0 [swuncons] [+] hylomorphism'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
|
||||
|
|
@ -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">'[step] help'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[step] help'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">Run</span> <span class="n">a</span> <span class="n">quoted</span> <span class="n">program</span> <span class="n">on</span> <span class="n">each</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">a</span> <span class="n">sequence</span><span class="o">.</span>
|
||||
|
|
@ -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">'sum == 0 swap [+] step'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sum == 0 swap [+] step'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[5 4 3 2 1] sum'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">15</span>
|
||||
|
|
@ -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"><=</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 factorial'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'5 factorial'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">120</span>
|
||||
|
|
@ -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">'tails == [] swap [not] [pop] [rest dup [swons] dip] primrec'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'tails == [] swap [not] [pop] [rest dup [swons] dip] primrec'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] tails'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 2 3] tails'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[]</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span><span class="p">]]</span>
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Recursion Combinators</a><ul>
|
||||
<li><a class="reference internal" href="#designing-recursive-functions">Designing Recursive Functions</a></li>
|
||||
<li><a class="reference internal" href="#primitive-recursive-functions">Primitive Recursive Functions</a></li>
|
||||
<li><a class="reference internal" href="#hylomorphism">Hylomorphism</a></li>
|
||||
<li><a class="reference internal" href="#hylomorphism-in-joy">Hylomorphism in Joy</a></li>
|
||||
<li><a class="reference internal" href="#derivation-of-hylomorphism-combinator">Derivation of <code class="docutils literal notranslate"><span class="pre">hylomorphism</span></code> combinator</a><ul>
|
||||
<li><a class="reference internal" href="#example-finding-triangular-numbers">Example: Finding Triangular Numbers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#four-specializations">Four Specializations</a><ul>
|
||||
<li><a class="reference internal" href="#h1"><code class="docutils literal notranslate"><span class="pre">H1</span></code></a></li>
|
||||
<li><a class="reference internal" href="#h2"><code class="docutils literal notranslate"><span class="pre">H2</span></code></a></li>
|
||||
<li><a class="reference internal" href="#h3"><code class="docutils literal notranslate"><span class="pre">H3</span></code></a></li>
|
||||
<li><a class="reference internal" href="#h4"><code class="docutils literal notranslate"><span class="pre">H4</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#anamorphism">Anamorphism</a><ul>
|
||||
<li><a class="reference internal" href="#range-et-al-an-example-of-an-anamorphism-is-the-range-function-which-generates-the-list-of-integers-from-0-to-n-1-given-n"><code class="docutils literal notranslate"><span class="pre">range</span></code> et. al. An example of an anamorphism is the <code class="docutils literal notranslate"><span class="pre">range</span></code> function which generates the list of integers from 0 to <em>n</em> - 1 given <em>n</em>.</a><ul>
|
||||
<li><a class="reference internal" href="#range-with-h1"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H1</span></code></a></li>
|
||||
<li><a class="reference internal" href="#range-with-h2"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H2</span></code></a></li>
|
||||
<li><a class="reference internal" href="#range-with-h3"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H3</span></code></a></li>
|
||||
<li><a class="reference internal" href="#range-with-h4"><code class="docutils literal notranslate"><span class="pre">range</span></code> with <code class="docutils literal notranslate"><span class="pre">H4</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#catamorphism">Catamorphism</a><ul>
|
||||
<li><a class="reference internal" href="#the-step-combinator">The <code class="docutils literal notranslate"><span class="pre">step</span></code> combinator</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#example-factorial-function">Example: Factorial Function</a></li>
|
||||
<li><a class="reference internal" href="#example-tails">Example: <code class="docutils literal notranslate"><span class="pre">tails</span></code></a></li>
|
||||
<li><a class="reference internal" href="#conclusion-patterns-of-recursion">Conclusion: Patterns of Recursion</a><ul>
|
||||
<li><a class="reference internal" href="#hylo-ana-cata">Hylo-, Ana-, Cata-</a></li>
|
||||
<li><a class="reference internal" href="#para">Para-, ?-, ?-</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#appendix-fun-with-symbols">Appendix: Fun with Symbols</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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. a function that adds new functions to the
|
||||
dictionary. However, there’s no function that does that. Adding a new
|
||||
function to the dictionary is a meta-interpreter action, you have to do
|
||||
it in Python, not Joy.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="kn">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">notebook_preamble</span> <span class="k">import</span> <span class="n">D</span><span class="p">,</span> <span class="n">J</span><span class="p">,</span> <span class="n">V</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="section" id="a-long-trace">
|
||||
<h2>A long trace<a class="headerlink" href="#a-long-trace" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">23</span> <span class="mi">18</span><span class="p">]</span> <span class="n">average</span>
|
||||
|
|
@ -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">'size'</span><span class="p">]</span> <span class="o">=</span> <span class="n">size</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">D</span><span class="p">[</span><span class="s1">'size'</span><span class="p">]</span> <span class="o">=</span> <span class="n">size</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="a-shorter-trace">
|
||||
<h2>A shorter trace<a class="headerlink" href="#a-shorter-trace" title="Permalink to this headline">¶</a></h2>
|
||||
<p>You can see that <code class="docutils literal notranslate"><span class="pre">size</span></code> now executes in a single step.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[23 18] average'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">23</span> <span class="mi">18</span><span class="p">]</span> <span class="n">average</span>
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Replacing Functions in the Dictionary</a><ul>
|
||||
<li><a class="reference internal" href="#a-long-trace">A long trace</a></li>
|
||||
<li><a class="reference internal" href="#replacing-size-with-a-python-version">Replacing <code class="docutils literal notranslate"><span class="pre">size</span></code> with a Python version</a></li>
|
||||
<li><a class="reference internal" href="#a-shorter-trace">A shorter trace</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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 couldn’t be
|
||||
reimplemented in terms of e.g. Python threads. I am not concerned with
|
||||
reimplemented in terms of e.g. Python threads. I am not concerned with
|
||||
performance of the system just yet, only the elegance of the code it
|
||||
allows us to write.</p>
|
||||
<div class="section" id="cleave">
|
||||
|
|
@ -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> couldn’t distribute
|
||||
the <code class="docutils literal notranslate"><span class="pre">Q</span></code> function over e.g. a pool of worker CPUs.</p>
|
||||
the <code class="docutils literal notranslate"><span class="pre">Q</span></code> function over e.g. a pool of worker CPUs.</p>
|
||||
</div>
|
||||
<div class="section" id="pam">
|
||||
<h3><code class="docutils literal notranslate"><span class="pre">pam</span></code><a class="headerlink" href="#pam" title="Permalink to this headline">¶</a></h3>
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">The Four Fundamental Operations of Definite Action</a><ul>
|
||||
<li><a class="reference internal" href="#sequence">Sequence</a></li>
|
||||
<li><a class="reference internal" href="#branch">Branch</a><ul>
|
||||
<li><a class="reference internal" href="#ifte"><code class="docutils literal notranslate"><span class="pre">ifte</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#loop">Loop</a><ul>
|
||||
<li><a class="reference internal" href="#while"><code class="docutils literal notranslate"><span class="pre">while</span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#parallel">Parallel</a><ul>
|
||||
<li><a class="reference internal" href="#cleave"><code class="docutils literal notranslate"><span class="pre">cleave</span></code></a></li>
|
||||
<li><a class="reference internal" href="#apply-functions">“Apply” Functions</a></li>
|
||||
<li><a class="reference internal" href="#map"><code class="docutils literal notranslate"><span class="pre">map</span></code></a></li>
|
||||
<li><a class="reference internal" href="#pam"><code class="docutils literal notranslate"><span class="pre">pam</span></code></a></li>
|
||||
<li><a class="reference internal" href="#handling-other-kinds-of-join">Handling Other Kinds of Join</a><ul>
|
||||
<li><a class="reference internal" href="#first-to-finish">first-to-finish</a></li>
|
||||
<li><a class="reference internal" href="#fulminators">“Fulminators”</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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">'''</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
|
||||
|
||||
<span class="s1"> _treestep_0 == [[not] swap] dip</span>
|
||||
<span class="s1"> _treestep_1 == [dip] cons [uncons] swoncat</span>
|
||||
|
|
@ -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">'sumtree == [pop 0] [] [sum +] treestep'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'sumtree == [pop 0] [] [sum +] treestep'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Running this function on an empty tree value gives zero:</p>
|
||||
|
|
@ -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">'[] sumtree'</span><span class="p">)</span> <span class="c1"># Empty tree.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[] sumtree'</span><span class="p">)</span> <span class="c1"># Empty tree.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">0</span>
|
||||
|
|
@ -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">'[23] sumtree'</span><span class="p">)</span> <span class="c1"># No child trees.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23] sumtree'</span><span class="p">)</span> <span class="c1"># No child trees.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 []] sumtree'</span><span class="p">)</span> <span class="c1"># Child tree, empty.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 []] sumtree'</span><span class="p">)</span> <span class="c1"># Child tree, empty.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">23</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [4]] [3]] sumtree'</span><span class="p">)</span> <span class="c1"># Non-empty child trees.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [4]] [3]] sumtree'</span><span class="p">)</span> <span class="c1"># Non-empty child trees.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">32</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] sumtree'</span><span class="p">)</span> <span class="c1"># Etc...</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] sumtree'</span><span class="p">)</span> <span class="c1"># Etc...</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">49</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep'</span><span class="p">)</span> <span class="c1"># Alternate "spelling".</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep'</span><span class="p">)</span> <span class="c1"># Alternate "spelling".</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">49</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep'</span><span class="p">)</span> <span class="c1"># Replace each node.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep'</span><span class="p">)</span> <span class="c1"># Replace each node.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">23</span> <span class="p">[</span><span class="mi">23</span> <span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="p">[</span><span class="mi">23</span><span class="p">]]</span> <span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="p">[</span><span class="mi">23</span> <span class="p">[]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">1</span><span class="p">]]</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[]]]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">6</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep'</span><span class="p">)</span> <span class="c1"># Combine replace and sum into one function.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span>
|
||||
|
|
@ -277,7 +276,7 @@ all nodes in a tree with this function:</p>
|
|||
</pre></div>
|
||||
</div>
|
||||
<p>This doesn’t quite work:</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">3</span> <span class="s1">'B'</span> <span class="s1">'B'</span>
|
||||
|
|
@ -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">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [first] [flatten cons] treestep'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">2</span> <span class="mi">9</span> <span class="mi">5</span> <span class="mi">4</span> <span class="mi">8</span> <span class="mi">6</span> <span class="mi">7</span><span class="p">]</span>
|
||||
|
|
@ -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"><</span> <span class="n">swons</span> <span class="n">concat</span><span class="p">]</span> <span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="n">treestep</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll< swons concat] treestep'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [uncons pop] [i roll< swons concat] treestep'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span> <span class="mi">5</span> <span class="mi">6</span> <span class="mi">7</span> <span class="mi">8</span> <span class="mi">9</span><span class="p">]</span>
|
||||
|
|
@ -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">'[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="s1">'key'</span> <span class="s1">'value'</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[[</span><span class="s1">'left'</span><span class="p">]</span> <span class="p">[</span><span class="s1">'right'</span><span class="p">]]</span> <span class="p">[[</span><span class="ow">not</span><span class="p">]</span> <span class="p">[</span><span class="s1">'B'</span><span class="p">]</span> <span class="p">[</span><span class="n">uncons</span> <span class="p">[</span><span class="s1">'N'</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="p">[</span><span class="s1">'C'</span><span class="p">]</span> <span class="n">genrec</span><span class="p">]</span> <span class="s1">'C'</span>
|
||||
|
|
@ -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">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] ["N"] [step] treegrind'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] ["N"] [step] treegrind'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">9</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">5</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">8</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">6</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span> <span class="p">[</span><span class="mi">7</span> <span class="mi">0</span><span class="p">]</span> <span class="s1">'N'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Sum the nodes’ keys.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [pop] [first +] [step] treegrind'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="mi">44</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Rebuild the tree using <code class="docutils literal notranslate"><span class="pre">map</span></code> (imitating <code class="docutils literal notranslate"><span class="pre">treestep</span></code>.)</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]] [] [[100 +] infra] [map cons] treegrind'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[[</span><span class="mi">103</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">102</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[[</span><span class="mi">109</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">105</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">104</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]</span> <span class="p">[[</span><span class="mi">108</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[[</span><span class="mi">106</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">107</span> <span class="mi">0</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[]]]</span> <span class="p">[]]]</span> <span class="p">[]]]</span>
|
||||
|
|
@ -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">'''</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">DefinitionWrapper</span><span class="o">.</span><span class="n">add_definitions</span><span class="p">(</span><span class="s1">'''</span>
|
||||
|
||||
<span class="s1"> T> == pop [first] dip i</span>
|
||||
<span class="s1"> T< == pop [second] dip i</span>
|
||||
|
|
@ -461,7 +460,7 @@ equal):</p>
|
|||
<span class="s1">'''</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
|
||||
|
||||
<span class="s1">[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]</span>
|
||||
|
||||
|
|
@ -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">'''</span><span class="se">\</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'''</span><span class="se">\</span>
|
||||
|
||||
<span class="s1">[[3 13] [[2 12] [] []] [[9 19] [[5 15] [[4 14] [] []] [[8 18] [[6 16] [] [[7 17] [] []]] []]] []]]</span>
|
||||
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Treating Trees II: <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a><ul>
|
||||
<li><a class="reference internal" href="#derive-the-recursive-function">Derive the recursive function.</a></li>
|
||||
<li><a class="reference internal" href="#extract-the-givens-to-parameterize-the-program">Extract the givens to parameterize the program.</a><ul>
|
||||
<li><a class="reference internal" href="#alternate-extract-the-givens-to-parameterize-the-program">(alternate) Extract the givens to parameterize the program.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#define-treestep">Define <code class="docutils literal notranslate"><span class="pre">treestep</span></code></a></li>
|
||||
<li><a class="reference internal" href="#examples">Examples</a></li>
|
||||
<li><a class="reference internal" href="#redefining-the-ordered-binary-tree-in-terms-of-treestep">Redefining the Ordered Binary Tree in terms of <code class="docutils literal notranslate"><span class="pre">treestep</span></code>.</a><ul>
|
||||
<li><a class="reference internal" href="#traversal">Traversal</a></li>
|
||||
<li><a class="reference internal" href="#in-order-traversal">In-order traversal</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#with-treegrind">With <code class="docutils literal notranslate"><span class="pre">treegrind</span></code>?</a></li>
|
||||
<li><a class="reference internal" href="#treegrind-with-step"><code class="docutils literal notranslate"><span class="pre">treegrind</span></code> with <code class="docutils literal notranslate"><span class="pre">step</span></code></a></li>
|
||||
<li><a class="reference internal" href="#do-we-have-the-flexibility-to-reimplement-tree-get">Do we have the flexibility to reimplement <code class="docutils literal notranslate"><span class="pre">Tree-get</span></code>?</a><ul>
|
||||
<li><a class="reference internal" href="#the-predicate-p">The predicate <code class="docutils literal notranslate"><span class="pre">P</span></code></a></li>
|
||||
<li><a class="reference internal" href="#e"><code class="docutils literal notranslate"><span class="pre">E</span></code></a></li>
|
||||
<li><a class="reference internal" href="#t-and-t"><code class="docutils literal notranslate"><span class="pre">T<</span></code> and <code class="docutils literal notranslate"><span class="pre">T></span></code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference internal" href="#putting-it-together">Putting it together</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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">'</span><span class="si">%(message)s</span><span class="s1">'</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">'product'</span><span class="p">]</span>
|
||||
<span class="nb">globals</span><span class="p">()</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">D</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="section" id="an-example">
|
||||
<h2>An Example<a class="headerlink" href="#an-example" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rrest</span><span class="p">,</span> <span class="n">ccons</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span> <span class="o">=</span> <span class="n">infer</span><span class="p">(</span><span class="n">pop</span><span class="p">,</span> <span class="n">swap</span><span class="p">,</span> <span class="n">rolldown</span><span class="p">,</span> <span class="n">rrest</span><span class="p">,</span> <span class="n">ccons</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>25 (--) ∘ pop swap rolldown rrest ccons
|
||||
|
|
@ -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">'0 1 2 [3 4]'</span><span class="p">)</span> <span class="c1"># reverse order</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'0 1 2 [3 4]'</span><span class="p">)</span> <span class="c1"># reverse order</span>
|
||||
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span> <span class="mi">4</span><span class="p">]</span> <span class="mi">2</span> <span class="mi">1</span> <span class="mi">0</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="n">u</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a1</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">a2</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a4</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">a5</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
|
||||
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -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">'[2 3]'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'[2 3]'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fo</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># output side, not input side</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">u</span> <span class="o">=</span> <span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fo</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># output side, not input side</span>
|
||||
<span class="n">u</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">{</span><span class="n">a2</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="n">a3</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="n">s2</span><span class="p">:</span> <span class="p">(),</span> <span class="n">s1</span><span class="p">:</span> <span class="p">()}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">g</span> <span class="o">=</span> <span class="n">reify</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="p">(</span><span class="n">fi</span><span class="p">,</span> <span class="n">fo</span><span class="p">))</span>
|
||||
<span class="nb">print</span> <span class="n">doc_from_stack_effect</span><span class="p">(</span><span class="o">*</span><span class="n">g</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
|
|
@ -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">'"two"'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">e</span> <span class="o">=</span> <span class="n">text_to_expression</span><span class="p">(</span><span class="s1">'"two"'</span><span class="p">)</span>
|
||||
<span class="nb">print</span> <span class="n">stack_to_string</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="s1">'two'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">unify</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">fi</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="n">JoyTypeError</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span>
|
||||
<span class="nb">print</span> <span class="n">err</span>
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Type Checking</a><ul>
|
||||
<li><a class="reference internal" href="#an-example">An Example</a></li>
|
||||
<li><a class="reference internal" href="#unification-works-in-reverse">Unification Works “in Reverse”</a></li>
|
||||
<li><a class="reference internal" href="#failing-a-check">Failing a Check</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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
|
|
@ -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 — 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 aren’t any complex datastructures, just ints, floats,
|
||||
strings, Symbols (strings that are names of functions) and sequences
|
||||
(aka lists, aka quoted literals, aka aggregates, etc…), but we can
|
||||
build
|
||||
(aka lists, aka quoted literals, aka aggregates, etc…), but we can build
|
||||
<a class="reference external" href="https://en.wikipedia.org/wiki/Tree_%28data_structure%29">trees</a> out
|
||||
of sequences.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8]'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8]'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
|
||||
|
|
@ -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">'z-down == [] swap uncons swap'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'z-down == [] swap uncons swap'</span><span class="p">)</span>
|
||||
<span class="n">define</span><span class="p">(</span><span class="s1">'z-up == swons swap shunt'</span><span class="p">)</span>
|
||||
<span class="n">define</span><span class="p">(</span><span class="s1">'z-right == [swons] cons dip uncons swap'</span><span class="p">)</span>
|
||||
<span class="n">define</span><span class="p">(</span><span class="s1">'z-left == swons [uncons swap] dip swap'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] z-down'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] z-down'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="n">z</span><span class="o">-</span><span class="n">down</span>
|
||||
|
|
@ -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">'[] [[2 [3 4 25 6] 7] 8] 1 z-right'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[] [[2 [3 4 25 6] 7] 8] 1 z-right'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="mi">1</span> <span class="n">z</span><span class="o">-</span><span class="n">right</span>
|
||||
|
|
@ -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">'[1] [8] [2 [3 4 25 6] 7] z-down'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 25 6] 7] z-down'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">2</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [] [[3 4 25 6] 7] 2 z-right'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [] [[3 4 25 6] 7] 2 z-right'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 25 6] z-down'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 25 6] z-down'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">3</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [] [4 25 6] 3 z-right'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [] [4 25 6] 3 z-right'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">4</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3] [25 6] 4 z-right'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3] [25 6] 4 z-right'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">25</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 25 sqr'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 25 sqr'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">625</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 625 z-up'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [4 3] [6] 625 z-up'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="p">[</span><span class="mi">4</span> <span class="mi">3</span><span class="p">]</span> <span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="mi">625</span> <span class="n">z</span><span class="o">-</span><span class="n">up</span>
|
||||
|
|
@ -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">'[1] [8] [2] [7] [3 4 625 6] z-up'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2] [7] [3 4 625 6] z-up'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">[</span><span class="mi">8</span><span class="p">]</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 625 6] 7] z-up'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1] [8] [2 [3 4 625 6] 7] z-up'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
|
||||
|
|
@ -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">'[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">25</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span> <span class="p">[[[[[[</span><span class="n">sqr</span><span class="p">]</span> <span class="n">dipd</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">infra</span><span class="p">]</span> <span class="n">dip</span><span class="p">]</span> <span class="n">infra</span>
|
||||
|
|
@ -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 isn’t hard to make.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Z == [[] cons cons] step i'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">define</span><span class="p">(</span><span class="s1">'Z == [[] cons cons] step i'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Here it is in action in a simplified scenario.</p>
|
||||
<div class="highlight-ipython2 notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [2 3 4] Z'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">V</span><span class="p">(</span><span class="s1">'1 [2 3 4] Z'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span> <span class="o">.</span> <span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="mi">3</span> <span class="mi">4</span><span class="p">]</span> <span class="n">Z</span>
|
||||
|
|
@ -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">'[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z'</span><span class="p">)</span>
|
||||
<div class="code ipython2 highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">J</span><span class="p">(</span><span class="s1">'[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z'</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span> <span class="p">[</span><span class="mi">2</span> <span class="p">[</span><span class="mi">3</span> <span class="mi">4</span> <span class="mi">625</span> <span class="mi">6</span><span class="p">]</span> <span class="mi">7</span><span class="p">]</span> <span class="mi">8</span><span class="p">]</span>
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
<h3><a href="../index.html">Table Of Contents</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Traversing Datastructures with Zippers</a><ul>
|
||||
<li><a class="reference internal" href="#trees">Trees</a></li>
|
||||
<li><a class="reference internal" href="#zipper-in-joy">Zipper in Joy</a></li>
|
||||
<li><a class="reference internal" href="#dip-and-infra"><code class="docutils literal notranslate"><span class="pre">dip</span></code> and <code class="docutils literal notranslate"><span class="pre">infra</span></code></a></li>
|
||||
<li><a class="reference internal" href="#z"><code class="docutils literal notranslate"><span class="pre">Z</span></code></a></li>
|
||||
<li><a class="reference internal" href="#addressing">Addressing</a></li>
|
||||
<li><a class="reference internal" href="#determining-the-right-path-for-an-item-in-a-tree">Determining the right “path” for an item in a tree.</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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öial’s Rules</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html#part-i-poials-rules">Part I: Pöial’s Rules</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html#part-ii-implementation">Part II: Implementation</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html#part-iii-compiling-yin-functions">Part III: Compiling Yin Functions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html#part-iv-types-and-subtypes-of-arguments">Part IV: Types and Subtypes of Arguments</a></li>
|
||||
|
|
@ -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">Brzozowski’s Derivatives of Regular Expressions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#brzozowskis-derivatives-of-regular-expressions">Brzozowski’s Derivatives of Regular Expressions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#implementation">Implementation</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#let-s-try-it-out">Let’s try it out…</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#lets-try-it-out">Let’s try it out…</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#larger-alphabets">Larger Alphabets</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#state-machine">State Machine</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html#reversing-the-derivatives-to-generate-matching-strings">Reversing the Derivatives to Generate Matching Strings</a></li>
|
||||
|
|
@ -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">Newton’s method</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Zipper.html">Traversing Datastructures with Zippers</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Types.html">The Blissful Elegance of Typing Joy</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="TypeChecking.html">Type Checking</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="NoUpdates.html">No Updates</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Categorical.html">Categorical Programming</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="The_Four_Operations.html">The Four Fundamental Operations of Definite Action</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="Derivatives_of_Regular_Expressions.html">∂RE</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<div class="sphinxsidebarwrapper"><div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../index.html">Documentation overview</a><ul>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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 — 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>
|
||||
|
|
|
|||
|
|
@ -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 — 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 TracePrinter’s history.
|
||||
Pass this method as the <code class="docutils literal notranslate"><span class="pre">viewer</span></code> argument to the <a class="reference internal" href="joy.html#joy.joy.joy" title="joy.joy.joy"><code class="xref py py-func docutils literal notranslate"><span class="pre">joy.joy.joy()</span></code></a> function.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><ul class="simple">
|
||||
<li><p><strong>quote</strong> (<em>stack</em>) – A stack.</p></li>
|
||||
<li><p><strong>expression</strong> (<em>stack</em>) – A stack.</p></li>
|
||||
<table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first last simple">
|
||||
<li><strong>quote</strong> (<em>stack</em>) – A stack.</li>
|
||||
<li><strong>expression</strong> (<em>stack</em>) – A stack.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dl class="function">
|
||||
<dt id="joy.utils.pretty_print.trace">
|
||||
<code class="sig-prename descclassname">joy.utils.pretty_print.</code><code class="sig-name descname">trace</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">expression</span></em>, <em class="sig-param"><span class="n">dictionary</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#trace"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.trace" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">joy.utils.pretty_print.</code><code class="descname">trace</code><span class="sig-paren">(</span><em>stack</em>, <em>expression</em>, <em>dictionary</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/pretty_print.html#trace"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.pretty_print.trace" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Evaluate a Joy expression on a stack and print a trace.</p>
|
||||
<p>This function is just like the <cite>i</cite> combinator but it also prints a
|
||||
trace of the evaluation</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><ul class="simple">
|
||||
<li><p><strong>stack</strong> (<em>stack</em>) – The stack.</p></li>
|
||||
<li><p><strong>expression</strong> (<em>stack</em>) – The expression to evaluate.</p></li>
|
||||
<li><p><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</p></li>
|
||||
<table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
|
||||
<li><strong>stack</strong> (<em>stack</em>) – The stack.</li>
|
||||
<li><strong>expression</strong> (<em>stack</em>) – The expression to evaluate.</li>
|
||||
<li><strong>dictionary</strong> (<em>dict</em>) – A <code class="docutils literal notranslate"><span class="pre">dict</span></code> mapping names to Joy functions.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt class="field-even">Return type</dt>
|
||||
<dd class="field-even"><p>(stack, (), dictionary)</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">(stack, (), dictionary)</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</dd></dl>
|
||||
|
||||
</div>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 — 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>
|
||||
|
|
|
|||
|
|
@ -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 — 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
|
|
@ -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… — 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">-></span> <span class="s1">'top second ...'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><p><strong>expression</strong> (<em>stack</em>) – A stack.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Return type</dt>
|
||||
<dd class="field-even"><p>str</p>
|
||||
</dd>
|
||||
</dl>
|
||||
<table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>expression</strong> (<em>stack</em>) – A stack.</td>
|
||||
</tr>
|
||||
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">str</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dl class="function">
|
||||
<dt id="joy.utils.stack.iter_stack">
|
||||
<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">iter_stack</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#iter_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.iter_stack" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">joy.utils.stack.</code><code class="descname">iter_stack</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#iter_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.iter_stack" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Iterate through the items on the stack.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><p><strong>stack</strong> (<em>stack</em>) – A stack.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Return type</dt>
|
||||
<dd class="field-even"><p>iterator</p>
|
||||
</dd>
|
||||
</dl>
|
||||
<table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>stack</strong> (<em>stack</em>) – A stack.</td>
|
||||
</tr>
|
||||
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">iterator</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dl class="function">
|
||||
<dt id="joy.utils.stack.list_to_stack">
|
||||
<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">list_to_stack</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">el</span></em>, <em class="sig-param"><span class="n">stack</span><span class="o">=</span><span class="default_value">()</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#list_to_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.list_to_stack" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">joy.utils.stack.</code><code class="descname">list_to_stack</code><span class="sig-paren">(</span><em>el</em>, <em>stack=()</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#list_to_stack"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.list_to_stack" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Convert a Python list (or other sequence) to a Joy stack:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span> <span class="o">-></span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="p">())))</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><ul class="simple">
|
||||
<li><p><strong>el</strong> (<em>list</em>) – A Python list or other sequence (iterators and generators
|
||||
won’t work because <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> is called on <code class="docutils literal notranslate"><span class="pre">el</span></code>.)</p></li>
|
||||
<li><p><strong>stack</strong> (<em>stack</em>) – A stack, optional, defaults to the empty stack.</p></li>
|
||||
<table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
|
||||
<li><strong>el</strong> (<em>list</em>) – A Python list or other sequence (iterators and generators
|
||||
won’t work because <code class="docutils literal notranslate"><span class="pre">reverse()</span></code> is called on <code class="docutils literal notranslate"><span class="pre">el</span></code>.)</li>
|
||||
<li><strong>stack</strong> (<em>stack</em>) – A stack, optional, defaults to the empty stack.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt class="field-even">Return type</dt>
|
||||
<dd class="field-even"><p>stack</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">stack</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dl class="function">
|
||||
<dt id="joy.utils.stack.pick">
|
||||
<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">pick</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em>, <em class="sig-param"><span class="n">n</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#pick"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.pick" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">joy.utils.stack.</code><code class="descname">pick</code><span class="sig-paren">(</span><em>stack</em>, <em>n</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#pick"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.pick" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Return the nth item on the stack.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><ul class="simple">
|
||||
<li><p><strong>stack</strong> (<em>stack</em>) – A stack.</p></li>
|
||||
<li><p><strong>n</strong> (<em>int</em>) – An index into the stack.</p></li>
|
||||
<table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><ul class="first simple">
|
||||
<li><strong>stack</strong> (<em>stack</em>) – A stack.</li>
|
||||
<li><strong>n</strong> (<em>int</em>) – An index into the stack.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt class="field-even">Raises</dt>
|
||||
<dd class="field-even"><ul class="simple">
|
||||
<li><p><strong>ValueError</strong> – if <code class="docutils literal notranslate"><span class="pre">n</span></code> is less than zero.</p></li>
|
||||
<li><p><strong>IndexError</strong> – if <code class="docutils literal notranslate"><span class="pre">n</span></code> is equal to or greater than the length of <code class="docutils literal notranslate"><span class="pre">stack</span></code>.</p></li>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="field-even field"><th class="field-name">Raises:</th><td class="field-body"><ul class="first simple">
|
||||
<li><strong>ValueError</strong> – if <code class="docutils literal notranslate"><span class="pre">n</span></code> is less than zero.</li>
|
||||
<li><strong>IndexError</strong> – if <code class="docutils literal notranslate"><span class="pre">n</span></code> is equal to or greater than the length of <code class="docutils literal notranslate"><span class="pre">stack</span></code>.</li>
|
||||
</ul>
|
||||
</dd>
|
||||
<dt class="field-odd">Return type</dt>
|
||||
<dd class="field-odd"><p>whatever</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body"><p class="first last">whatever</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dl class="function">
|
||||
<dt id="joy.utils.stack.stack_to_string">
|
||||
<code class="sig-prename descclassname">joy.utils.stack.</code><code class="sig-name descname">stack_to_string</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">stack</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#stack_to_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.stack_to_string" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">joy.utils.stack.</code><code class="descname">stack_to_string</code><span class="sig-paren">(</span><em>stack</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/stack.html#stack_to_string"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.stack.stack_to_string" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Return a “pretty print” string for a stack.</p>
|
||||
<p>The items are written right-to-left:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">top</span><span class="p">,</span> <span class="p">(</span><span class="n">second</span><span class="p">,</span> <span class="o">...</span><span class="p">))</span> <span class="o">-></span> <span class="s1">'... second top'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Parameters</dt>
|
||||
<dd class="field-odd"><p><strong>stack</strong> (<em>stack</em>) – A stack.</p>
|
||||
</dd>
|
||||
<dt class="field-even">Return type</dt>
|
||||
<dd class="field-even"><p>str</p>
|
||||
</dd>
|
||||
</dl>
|
||||
<table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>stack</strong> (<em>stack</em>) – A stack.</td>
|
||||
</tr>
|
||||
<tr class="field-even field"><th class="field-name">Return type:</th><td class="field-body">str</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</dd></dl>
|
||||
|
||||
</div>
|
||||
|
|
@ -201,36 +218,17 @@ won’t 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 @@ won’t 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 @@ won’t 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>
|
||||
|
|
|
|||
|
|
@ -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 — 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 don’t lead to type conflicts.</p>
|
||||
<dl class="py attribute">
|
||||
<dl class="attribute">
|
||||
<dt id="joy.utils.types.KleeneStar.kind">
|
||||
<code class="sig-name descname">kind</code><a class="headerlink" href="#joy.utils.types.KleeneStar.kind" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descname">kind</code><a class="headerlink" href="#joy.utils.types.KleeneStar.kind" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>alias of <a class="reference internal" href="#joy.utils.types.AnyJoyType" title="joy.utils.types.AnyJoyType"><code class="xref py py-class docutils literal notranslate"><span class="pre">AnyJoyType</span></code></a></p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dl class="class">
|
||||
<dt id="joy.utils.types.NumberJoyType">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">NumberJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#NumberJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.NumberJoyType" title="Permalink to this definition">¶</a></dt>
|
||||
<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">NumberJoyType</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#NumberJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.NumberJoyType" title="Permalink to this definition">¶</a></dt>
|
||||
<dd></dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt id="joy.utils.types.NumberStarJoyType">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">NumberStarJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#NumberStarJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.NumberStarJoyType" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><dl class="py attribute">
|
||||
<dt id="joy.utils.types.NumberStarJoyType.kind">
|
||||
<code class="sig-name descname">kind</code><a class="headerlink" href="#joy.utils.types.NumberStarJoyType.kind" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>alias of <a class="reference internal" href="#joy.utils.types.NumberJoyType" title="joy.utils.types.NumberJoyType"><code class="xref py py-class docutils literal notranslate"><span class="pre">NumberJoyType</span></code></a></p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dl class="class">
|
||||
<dt id="joy.utils.types.StackJoyType">
|
||||
<em class="property">class </em><code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">StackJoyType</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">number</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#StackJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.StackJoyType" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><dl class="py attribute">
|
||||
<em class="property">class </em><code class="descclassname">joy.utils.types.</code><code class="descname">StackJoyType</code><span class="sig-paren">(</span><em>number</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#StackJoyType"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.StackJoyType" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><dl class="attribute">
|
||||
<dt id="joy.utils.types.StackJoyType.accept">
|
||||
<code class="sig-name descname">accept</code><a class="headerlink" href="#joy.utils.types.StackJoyType.accept" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>alias of <code class="xref py py-class docutils literal notranslate"><span class="pre">builtins.tuple</span></code></p>
|
||||
<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 it’s indeterminate (because I haven’t entered it into
|
||||
the FUNCTIONS dict yet.)</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py function">
|
||||
<dl class="function">
|
||||
<dt id="joy.utils.types.uni_unify">
|
||||
<code class="sig-prename descclassname">joy.utils.types.</code><code class="sig-name descname">uni_unify</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">u</span></em>, <em class="sig-param"><span class="n">v</span></em>, <em class="sig-param"><span class="n">s</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#uni_unify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.uni_unify" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">joy.utils.types.</code><code class="descname">uni_unify</code><span class="sig-paren">(</span><em>u</em>, <em>v</em>, <em>s=None</em><span class="sig-paren">)</span><a class="reference internal" href="_modules/joy/utils/types.html#uni_unify"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#joy.utils.types.uni_unify" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Return a substitution dict representing a unifier for u and v.</p>
|
||||
</dd></dl>
|
||||
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -1,69 +1,69 @@
|
|||
∂RE
|
||||
===
|
||||
|
||||
Brzozowski's Derivatives of Regular Expressions
|
||||
Brzozowski’s Derivatives of Regular Expressions
|
||||
-----------------------------------------------
|
||||
|
||||
Legend:
|
||||
|
||||
::
|
||||
|
||||
∧ intersection
|
||||
∨ union
|
||||
∘ concatenation (see below)
|
||||
¬ complement
|
||||
ϕ empty set (aka ∅)
|
||||
λ singleton set containing just the empty string
|
||||
I set of all letters in alphabet
|
||||
∧ intersection
|
||||
∨ union
|
||||
∘ concatenation (see below)
|
||||
¬ complement
|
||||
ϕ empty set (aka ∅)
|
||||
λ singleton set containing just the empty string
|
||||
I set of all letters in alphabet
|
||||
|
||||
Derivative of a set ``R`` of strings and a string ``a``:
|
||||
|
||||
::
|
||||
|
||||
∂a(R)
|
||||
∂a(R)
|
||||
|
||||
∂a(a) → λ
|
||||
∂a(λ) → ϕ
|
||||
∂a(ϕ) → ϕ
|
||||
∂a(¬a) → ϕ
|
||||
∂a(R*) → ∂a(R)∘R*
|
||||
∂a(¬R) → ¬∂a(R)
|
||||
∂a(R∘S) → ∂a(R)∘S ∨ δ(R)∘∂a(S)
|
||||
∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
|
||||
∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
|
||||
∂a(a) → λ
|
||||
∂a(λ) → ϕ
|
||||
∂a(ϕ) → ϕ
|
||||
∂a(¬a) → ϕ
|
||||
∂a(R*) → ∂a(R)∘R*
|
||||
∂a(¬R) → ¬∂a(R)
|
||||
∂a(R∘S) → ∂a(R)∘S ∨ δ(R)∘∂a(S)
|
||||
∂a(R ∧ S) → ∂a(R) ∧ ∂a(S)
|
||||
∂a(R ∨ S) → ∂a(R) ∨ ∂a(S)
|
||||
|
||||
∂ab(R) = ∂b(∂a(R))
|
||||
∂ab(R) = ∂b(∂a(R))
|
||||
|
||||
Auxiliary predicate function ``δ`` (I call it ``nully``) returns either
|
||||
``λ`` if ``λ ⊆ R`` or ``ϕ`` otherwise:
|
||||
|
||||
::
|
||||
|
||||
δ(a) → ϕ
|
||||
δ(λ) → λ
|
||||
δ(ϕ) → ϕ
|
||||
δ(R*) → λ
|
||||
δ(¬R) δ(R)≟ϕ → λ
|
||||
δ(¬R) δ(R)≟λ → ϕ
|
||||
δ(R∘S) → δ(R) ∧ δ(S)
|
||||
δ(R ∧ S) → δ(R) ∧ δ(S)
|
||||
δ(R ∨ S) → δ(R) ∨ δ(S)
|
||||
δ(a) → ϕ
|
||||
δ(λ) → λ
|
||||
δ(ϕ) → ϕ
|
||||
δ(R*) → λ
|
||||
δ(¬R) δ(R)≟ϕ → λ
|
||||
δ(¬R) δ(R)≟λ → ϕ
|
||||
δ(R∘S) → δ(R) ∧ δ(S)
|
||||
δ(R ∧ S) → δ(R) ∧ δ(S)
|
||||
δ(R ∨ S) → δ(R) ∨ δ(S)
|
||||
|
||||
Some rules we will use later for "compaction":
|
||||
Some rules we will use later for “compaction”:
|
||||
|
||||
::
|
||||
|
||||
R ∧ ϕ = ϕ ∧ R = ϕ
|
||||
R ∧ ϕ = ϕ ∧ R = ϕ
|
||||
|
||||
R ∧ I = I ∧ R = R
|
||||
R ∧ I = I ∧ R = R
|
||||
|
||||
R ∨ ϕ = ϕ ∨ R = R
|
||||
R ∨ ϕ = ϕ ∨ R = R
|
||||
|
||||
R ∨ I = I ∨ R = I
|
||||
R ∨ I = I ∨ R = I
|
||||
|
||||
R∘ϕ = ϕ∘R = ϕ
|
||||
R∘ϕ = ϕ∘R = ϕ
|
||||
|
||||
R∘λ = λ∘R = R
|
||||
R∘λ = λ∘R = R
|
||||
|
||||
Concatination of sets: for two sets A and B the set A∘B is defined as:
|
||||
|
||||
|
|
@ -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
|
||||
I’m only going to use two symbols (at first) becaase this is enough to
|
||||
illustrate the algorithm and because you can represent any other
|
||||
alphabet with two symbols (if you had to.)
|
||||
|
||||
I chose the names ``O`` and ``l`` (uppercase "o" and lowercase "L") to
|
||||
I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
|
||||
look like ``0`` and ``1`` (zero and one) respectively.
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -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 I’m going to use tagged tuples. A *regular
|
||||
expression* is one of:
|
||||
|
||||
::
|
||||
|
||||
O
|
||||
l
|
||||
(KSTAR, R)
|
||||
(NOT, R)
|
||||
(AND, R, S)
|
||||
(CONS, R, S)
|
||||
(OR, R, S)
|
||||
O
|
||||
l
|
||||
(KSTAR, R)
|
||||
(NOT, R)
|
||||
(AND, R, S)
|
||||
(CONS, R, S)
|
||||
(OR, R, S)
|
||||
|
||||
Where ``R`` and ``S`` stand for *regular expressions*.
|
||||
|
||||
|
|
@ -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.
|
||||
Let’s 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...
|
||||
-------------------
|
||||
Let’s 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 you’ll see that we never use the “set-ness” of the symbols ``O``
|
||||
and ``l``. The only time Python set operators (``&`` and ``|``) appear
|
||||
is in the ``nully()`` function, and there they operate on (recursively
|
||||
computed) outputs of that function, never ``O`` and ``l``.
|
||||
|
|
@ -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 1’s and not ending in 01 nor composed of all 1’s.”
|
||||
|
||||
.. 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/>`__.) You’ll see that only
|
||||
paths that lead to one of the accepting states will match the regular
|
||||
expression. All other paths will terminate at one of the non-accepting
|
||||
states.
|
||||
|
||||
There's a happy path to ``g`` along 111:
|
||||
There’s a happy path to ``g`` along 111:
|
||||
|
||||
::
|
||||
|
||||
a→c→e→g
|
||||
a→c→e→g
|
||||
|
||||
After you reach ``g`` you're stuck there eating 1's until you see a 0,
|
||||
which takes you to the ``i→j→i|i→j→h→i`` "trap". You can't reach any
|
||||
After you reach ``g`` you’re stuck there eating 1’s until you see a 0,
|
||||
which takes you to the ``i→j→i|i→j→h→i`` “trap”. You can’t reach any
|
||||
other states from those two loops.
|
||||
|
||||
If you see a 0 before you see 111 you will reach ``b``, which forms
|
||||
another "trap" with ``d`` and ``f``. The only way out is another happy
|
||||
another “trap” with ``d`` and ``f``. The only way out is another happy
|
||||
path along 111 to ``h``:
|
||||
|
||||
::
|
||||
|
||||
b→d→f→h
|
||||
b→d→f→h
|
||||
|
||||
Once you have reached ``h`` you can see as many 1's or as many 0' in a
|
||||
row and still be either still at ``h`` (for 1's) or move to ``i`` (for
|
||||
0's). If you find yourself at ``i`` you can see as many 0's, or
|
||||
Once you have reached ``h`` you can see as many 1’s or as many 0’ in a
|
||||
row and still be either still at ``h`` (for 1’s) or move to ``i`` (for
|
||||
0’s). If you find yourself at ``i`` you can see as many 0’s, or
|
||||
repetitions of 10, as there are, but if you see just a 1 you move to
|
||||
``j``.
|
||||
|
||||
|
|
@ -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 arrow’s symbol.
|
||||
|
||||
If we label the initial RE ``a``, we can say:
|
||||
|
||||
::
|
||||
|
||||
a --0--> ∂0(a)
|
||||
a --1--> ∂1(a)
|
||||
a --0--> ∂0(a)
|
||||
a --1--> ∂1(a)
|
||||
|
||||
And so on, each new unique RE is a new state in the FSM table.
|
||||
|
||||
|
|
@ -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`` isn’t.
|
||||
|
||||
.. 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)*
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
Let’s 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:
|
||||
Let’s 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 you’ll see that we might be
|
||||
interested in generating an endless cycle of:
|
||||
|
||||
::
|
||||
|
||||
3 2 1 3 1 2 3
|
||||
3 2 1 3 1 2 3
|
||||
|
||||
To do this we want to encode the numbers as pairs of bits in a single
|
||||
int:
|
||||
|
||||
::
|
||||
|
||||
3 2 1 3 1 2 3
|
||||
0b 11 10 01 11 01 10 11 == 14811
|
||||
3 2 1 3 1 2 3
|
||||
0b 11 10 01 11 01 10 11 == 14811
|
||||
|
||||
And pick them off by masking with 3 (binary 11) and then shifting the
|
||||
int right two bits.
|
||||
|
|
@ -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
|
||||
that’s a little beyond the scope of this article. This solution does
|
||||
extra work, but not much, and we’re not using it “in production” as they
|
||||
say.)
|
||||
|
||||
Run 466 times
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
In the PE1 problem we are asked to sum all the multiples of three and
|
||||
five less than 1000. It's worked out that we need to use all seven
|
||||
five less than 1000. It’s worked out that we need to use all seven
|
||||
numbers sixty-six times and then four more.
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -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``:
|
||||
Let’s start with ``swons``:
|
||||
|
||||
::
|
||||
|
||||
[b a F] b+a swons
|
||||
[b+a b a F]
|
||||
[b a F] b+a swons
|
||||
[b+a b a F]
|
||||
|
||||
Considering this quote as a stack:
|
||||
|
||||
::
|
||||
|
||||
F a b b+a
|
||||
F a b b+a
|
||||
|
||||
We want to get it to:
|
||||
|
||||
::
|
||||
|
||||
F b b+a b
|
||||
F b b+a b
|
||||
|
||||
So:
|
||||
|
||||
::
|
||||
|
||||
F a b b+a popdd over
|
||||
F b b+a b
|
||||
F a b b+a popdd over
|
||||
F b b+a b
|
||||
|
||||
And therefore:
|
||||
|
||||
::
|
||||
|
||||
[b+a b a F] [popdd over] infra
|
||||
[b b+a b F]
|
||||
[b+a b a F] [popdd over] infra
|
||||
[b b+a b F]
|
||||
|
||||
But we can just use ``cons`` to carry ``b+a`` into the quote:
|
||||
|
||||
::
|
||||
|
||||
[b a F] b+a [popdd over] cons infra
|
||||
[b a F] [b+a popdd over] infra
|
||||
[b b+a b F]
|
||||
[b a F] b+a [popdd over] cons infra
|
||||
[b a F] [b+a popdd over] infra
|
||||
[b b+a b F]
|
||||
|
||||
Lastly:
|
||||
|
||||
::
|
||||
|
||||
[b b+a b F] uncons
|
||||
b [b+a b F]
|
||||
[b b+a b F] uncons
|
||||
b [b+a b F]
|
||||
|
||||
Putting it all together:
|
||||
|
||||
::
|
||||
|
||||
F == + [popdd over] cons infra uncons
|
||||
fib_gen == [1 1 F]
|
||||
F == + [popdd over] cons infra uncons
|
||||
fib_gen == [1 1 F]
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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 it’s straightforward to define ``PE2`` as a recursive function that
|
||||
generates terms in the Fibonacci sequence until they exceed four million
|
||||
and sums the even ones.
|
||||
|
||||
|
|
@ -503,18 +502,18 @@ and sums the even ones.
|
|||
4613732
|
||||
|
||||
|
||||
Here's the collected program definitions:
|
||||
Here’s the collected program definitions:
|
||||
|
||||
::
|
||||
|
||||
fib == + swons [popdd over] infra uncons
|
||||
fib_gen == [1 1 fib]
|
||||
fib == + swons [popdd over] infra uncons
|
||||
fib_gen == [1 1 fib]
|
||||
|
||||
even == dup 2 %
|
||||
>4M == 4000000 >
|
||||
even == dup 2 %
|
||||
>4M == 4000000 >
|
||||
|
||||
PE2.1 == even [+] [pop] branch
|
||||
PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
|
||||
PE2.1 == even [+] [pop] branch
|
||||
PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec
|
||||
|
||||
Even-valued Fibonacci Terms
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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 +
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
`Newton's method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
|
||||
`Newton’s method <https://en.wikipedia.org/wiki/Newton%27s_method>`__
|
||||
=====================================================================
|
||||
|
||||
Let's use the Newton-Raphson method for finding the root of an equation
|
||||
Let’s use the Newton-Raphson method for finding the root of an equation
|
||||
to write a function that can compute the square root of a number.
|
||||
|
||||
Cf. `"Why Functional Programming Matters" by John
|
||||
Cf. `“Why Functional Programming Matters” by John
|
||||
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__
|
||||
|
||||
.. code:: ipython2
|
||||
|
|
@ -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 we’re writing. If we let 1 be the initial approximation:
|
||||
|
||||
::
|
||||
|
||||
1 n 1 / + 2 /
|
||||
1 n/1 + 2 /
|
||||
1 n + 2 /
|
||||
n+1 2 /
|
||||
(n+1)/2
|
||||
1 n 1 / + 2 /
|
||||
1 n/1 + 2 /
|
||||
1 n + 2 /
|
||||
n+1 2 /
|
||||
(n+1)/2
|
||||
|
||||
The generator can be written as:
|
||||
|
||||
::
|
||||
|
||||
23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 23 [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 [23 over / + 2 /] [dup] swoncat make_generator
|
||||
1 [dup 23 over / + 2 /] make_generator
|
||||
23 1 swap [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 23 [over / + 2 /] cons [dup] swoncat make_generator
|
||||
1 [23 over / + 2 /] [dup] swoncat make_generator
|
||||
1 [dup 23 over / + 2 /] make_generator
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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...
|
||||
Let’s 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
|
|
@ -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 it’s the definition of the ``quadratic`` function:
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
|
||||
|
||||
Let's try it out:
|
||||
Let’s try it out:
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Let’s write a function that, given a positive integer, returns the sum
|
||||
of all positive integers less than that one. (In this case the types
|
||||
``A``, ``B`` and ``C`` are all ``int``.)
|
||||
|
||||
|
|
@ -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:
|
||||
Let’s 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
|
||||
generator’s output, in other words, whether ``F`` or ``G`` should run
|
||||
first in the recursive branch.
|
||||
|
||||
::
|
||||
|
||||
H1 == [P] [pop c] [G ] [dip F] genrec
|
||||
H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
|
||||
H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
|
||||
H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
|
||||
H1 == [P] [pop c] [G ] [dip F] genrec
|
||||
H2 == c swap [P] [pop] [G [F] dip ] [i] genrec
|
||||
H3 == [P] [pop c] [ [G] dupdip ] [dip F] genrec
|
||||
H4 == c swap [P] [pop] [ [F] dupdip G] [i] genrec
|
||||
|
||||
The working of the generator function ``G`` differs slightly for each.
|
||||
Consider the recursive branches:
|
||||
|
||||
::
|
||||
|
||||
... a G [H1] dip F w/ a G == a′ b
|
||||
... a G [H1] dip F w/ a G == a′ b
|
||||
|
||||
... c a G [F] dip H2 a G == b a′
|
||||
... c a G [F] dip H2 a G == b a′
|
||||
|
||||
... a [G] dupdip [H3] dip F a G == a′
|
||||
... a [G] dupdip [H3] dip F a G == a′
|
||||
|
||||
... c a [F] dupdip G H4 a G == a′
|
||||
... c a [F] dupdip G H4 a G == a′
|
||||
|
||||
The following four sections illustrate how these work, omitting the
|
||||
predicate evaluation.
|
||||
|
|
@ -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 you’ll see that the combiner ``F`` only
|
||||
gets to operate on the results of ``G``, it never “sees” the first value
|
||||
``a``. If the combiner and the generator both need to work on the
|
||||
current value then ``dup`` must be used, and the generator must produce
|
||||
one item instead of two (the b is instead the duplicate of a.)
|
||||
|
||||
::
|
||||
|
||||
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
|
||||
H3 == [P] [pop c] [[G] dupdip] [dip F] genrec
|
||||
|
||||
... a [G] dupdip [H3] dip F
|
||||
... a G a [H3] dip F
|
||||
... a′ a [H3] dip F
|
||||
... a′ H3 a F
|
||||
... a′ [G] dupdip [H3] dip F a F
|
||||
... a′ G a′ [H3] dip F a F
|
||||
... a″ a′ [H3] dip F a F
|
||||
... a″ H3 a′ F a F
|
||||
... a″ [G] dupdip [H3] dip F a′ F a F
|
||||
... a″ G a″ [H3] dip F a′ F a F
|
||||
... a‴ a″ [H3] dip F a′ F a F
|
||||
... a‴ H3 a″ F a′ F a F
|
||||
... a‴ pop c a″ F a′ F a F
|
||||
... c a″ F a′ F a F
|
||||
... d a′ F a F
|
||||
... d′ a F
|
||||
... d″
|
||||
... a [G] dupdip [H3] dip F
|
||||
... a G a [H3] dip F
|
||||
... a′ a [H3] dip F
|
||||
... a′ H3 a F
|
||||
... a′ [G] dupdip [H3] dip F a F
|
||||
... a′ G a′ [H3] dip F a F
|
||||
... a″ a′ [H3] dip F a F
|
||||
... a″ H3 a′ F a F
|
||||
... a″ [G] dupdip [H3] dip F a′ F a F
|
||||
... a″ G a″ [H3] dip F a′ F a F
|
||||
... a‴ a″ [H3] dip F a′ F a F
|
||||
... a‴ H3 a″ F a′ F a F
|
||||
... a‴ pop c a″ F a′ F a F
|
||||
... c a″ F a′ F a F
|
||||
... d a′ F a F
|
||||
... d′ a F
|
||||
... d″
|
||||
|
||||
``H4``
|
||||
~~~~~~
|
||||
|
|
@ -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.”
|
||||
|
|
|
|||
|
|
@ -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, there’s no function that does that. Adding a new
|
||||
function to the dictionary is a meta-interpreter action, you have to do
|
||||
it in Python, not Joy.
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 doesn’t *have*
|
||||
to be Boolean because Python’s rules for “truthiness” will be used to
|
||||
evaluate it. I reflect this in the structure of the stack effect comment
|
||||
of ``branch``, it will only accept Boolean values, and in the definition
|
||||
of ``ifte`` above by including ``not`` in the quote, which also has the
|
||||
|
|
@ -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 couldn’t be
|
||||
reimplemented in terms of e.g. Python threads. I am not concerned with
|
||||
performance of the system just yet, only the elegance of the code it
|
||||
allows us to write.
|
||||
|
||||
|
|
@ -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.)
|
||||
Elliott’s “Compiling to Categories” paper, et. al.)
|
||||
|
||||
Just a thought, if you ``cleave`` two jobs and one requires more time to
|
||||
finish than the other you'd like to be able to assign resources
|
||||
finish than the other you’d like to be able to assign resources
|
||||
accordingly so that they both finish at the same time.
|
||||
|
||||
"Apply" Functions
|
||||
“Apply” Functions
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
There are also ``app2`` and ``app3`` which run a single quote on more
|
||||
|
|
@ -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
|
||||
(I’m not sure why ``cleave`` was specified to take that value, I may
|
||||
make a combinator that does the same thing but without expecting a
|
||||
value.)
|
||||
|
||||
::
|
||||
|
||||
clv == [i] app2
|
||||
clv == [i] app2
|
||||
|
||||
[A] [B] clv
|
||||
------------------
|
||||
a b
|
||||
[A] [B] clv
|
||||
------------------
|
||||
a b
|
||||
|
||||
``map``
|
||||
~~~~~~~
|
||||
|
|
@ -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`` couldn’t 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 I’m not going to worry about
|
||||
it. (And I think the Categories can deal with it anyhow? Incremental
|
||||
evaluation, yeah?)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
Treating Trees II: ``treestep``
|
||||
===============================
|
||||
|
||||
Let's consider a tree structure, similar to one described `"Why
|
||||
functional programming matters" by John
|
||||
Let’s consider a tree structure, similar to one described `“Why
|
||||
functional programming matters” by John
|
||||
Hughes <https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf>`__,
|
||||
that consists of a node value followed by zero or more child trees. (The
|
||||
asterisk is meant to indicate the `Kleene
|
||||
|
|
@ -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 we’ll 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``.
|
||||
Let’s dive in. First, unquote the node and ``dip`` ``N``.
|
||||
|
||||
::
|
||||
|
||||
[node tree*] uncons [N] dip
|
||||
node [tree*] [N] dip
|
||||
node N [tree*]
|
||||
[node tree*] uncons [N] dip
|
||||
node [tree*] [N] dip
|
||||
node N [tree*]
|
||||
|
||||
Next, ``map`` ``K`` over the child trees and combine with ``C``.
|
||||
|
||||
::
|
||||
|
||||
node N [tree*] [K] map C
|
||||
node N [tree*] [K] map C
|
||||
node N [K.tree*] C
|
||||
node N [tree*] [K] map C
|
||||
node N [tree*] [K] map C
|
||||
node N [K.tree*] C
|
||||
|
||||
So:
|
||||
|
||||
::
|
||||
|
||||
J == uncons [N] dip [K] map C
|
||||
J == uncons [N] dip [K] map C
|
||||
|
||||
Plug it in and convert to ``genrec``:
|
||||
|
||||
::
|
||||
|
||||
K == [not] [B] [J ] ifte
|
||||
== [not] [B] [uncons [N] dip [K] map C] ifte
|
||||
== [not] [B] [uncons [N] dip] [map C] genrec
|
||||
K == [not] [B] [J ] ifte
|
||||
== [not] [B] [uncons [N] dip [K] map C] ifte
|
||||
== [not] [B] [uncons [N] dip] [map C] genrec
|
||||
|
||||
Extract the givens to parameterize the program.
|
||||
-----------------------------------------------
|
||||
|
|
@ -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 doesn’t 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
|
||||
Doesn’t work because ``map`` extracts the ``first`` item of whatever its
|
||||
mapped function produces. We have to return a list, rather than
|
||||
depositing our results directly on the stack.
|
||||
|
||||
::
|
||||
|
||||
[key value] N [left right] [K] map C
|
||||
[key value] N [left right] [K] map C
|
||||
|
||||
[key value] first [left right] [K] map flatten cons
|
||||
key [left right] [K] map flatten cons
|
||||
key [[lk] [rk] ] flatten cons
|
||||
key [ lk rk ] cons
|
||||
[key lk rk ]
|
||||
[key value] first [left right] [K] map flatten cons
|
||||
key [left right] [K] map flatten cons
|
||||
key [[lk] [rk] ] flatten cons
|
||||
key [ lk rk ] cons
|
||||
[key lk rk ]
|
||||
|
||||
So:
|
||||
|
||||
::
|
||||
|
||||
[] [first] [flatten cons] treestep
|
||||
[] [first] [flatten cons] treestep
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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 doesn’t include the ``map`` combinator, so
|
||||
the ``[C]`` function must arrange to use some combinator on the quoted
|
||||
recursive copy ``[K]``. With this function, the pattern for processing a
|
||||
non-empty node is:
|
||||
|
||||
::
|
||||
|
||||
node N [tree*] [K] C
|
||||
node N [tree*] [K] C
|
||||
|
||||
Plugging in our BTree structure:
|
||||
|
||||
::
|
||||
|
||||
[key value] N [left right] [K] C
|
||||
[key value] N [left right] [K] C
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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
|
||||
We’ll start by saying that the base-case (the key is not in the tree) is
|
||||
user defined, and the per-node function is just the query key literal:
|
||||
|
||||
::
|
||||
|
||||
[B] [query_key] [C] treegrind
|
||||
[B] [query_key] [C] treegrind
|
||||
|
||||
This means we just have to define ``C`` from:
|
||||
|
||||
::
|
||||
|
||||
[key value] query_key [left right] [K] C
|
||||
[key value] query_key [left right] [K] C
|
||||
|
||||
Let's try ``cmp``:
|
||||
Let’s try ``cmp``:
|
||||
|
||||
::
|
||||
|
||||
C == P [T>] [E] [T<] cmp
|
||||
C == P [T>] [E] [T<] cmp
|
||||
|
||||
[key value] query_key [left right] [K] P [T>] [E] [T<] cmp
|
||||
[key value] query_key [left right] [K] P [T>] [E] [T<] cmp
|
||||
|
||||
The predicate ``P``
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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 aren’t any complex datastructures, just ints, floats,
|
||||
strings, Symbols (strings that are names of functions) and sequences
|
||||
(aka lists, aka quoted literals, aka aggregates, etc...), but we can
|
||||
build
|
||||
(aka lists, aka quoted literals, aka aggregates, etc…), but we can build
|
||||
`trees <https://en.wikipedia.org/wiki/Tree_%28data_structure%29>`__ out
|
||||
of sequences.
|
||||
|
||||
|
|
@ -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
|
||||
Let’s use them to change 25 into 625. The first time a word is used I
|
||||
show the trace so you can see how it works. If we were going to use
|
||||
these a lot it would make sense to write Python versions for efficiency,
|
||||
but see below.
|
||||
|
|
@ -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 you’ll see that about half of it is the
|
||||
``dip`` and ``infra`` combinators de-quoting programs and “digging” into
|
||||
the subject datastructure. Instead of maintaining temporary results on
|
||||
the stack they are pushed into the pending expression (continuation).
|
||||
When ``sqr`` has run the rest of the pending expression rebuilds the
|
||||
|
|
@ -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 isn’t 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"
|
||||
It’s easy to read off (in reverse) the right sequence of “d” and “i”
|
||||
from the subject datastructure:
|
||||
|
||||
::
|
||||
|
||||
[ n [ n [ n n x ...
|
||||
i d i d i d d Bingo!
|
||||
[ n [ n [ n n x ...
|
||||
i d i d i d d Bingo!
|
||||
|
||||
|
|
|
|||
|
|
@ -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 doesn’t 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 “can’t 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. There’s a
|
||||
huge amount of incredibly useful stuff and I don’t see why Joy shouldn’t
|
||||
expose another interface for using it. (As an example, the symbolic
|
||||
expressions can be "lambdafied" into very fast versions, i.e. a function
|
||||
expressions can be “lambdafied” into very fast versions, i.e. a function
|
||||
that takes ``a``, ``b``, and ``c`` and computes the value of the root
|
||||
using just low-level fast code, bypassing Joy and Python. Also, Numpy,
|
||||
&c.)
|
||||
|
|
@ -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?
|
||||
What’s Fw?
|
||||
|
||||
::
|
||||
|
||||
u k z [pop odd] [Ft] [] ifte # the if statement
|
||||
[2 //] dip # k = k / 2 floordiv
|
||||
[sqr] dipd # u = u * u
|
||||
u k z [pop odd] [Ft] [] ifte # the if statement
|
||||
[2 //] dip # k = k / 2 floordiv
|
||||
[sqr] dipd # u = u * u
|
||||
|
||||
[[sqr] dip 2 //] dip # We can merge last two lines.
|
||||
[[sqr] dip 2 //] dip # We can merge last two lines.
|
||||
|
||||
Helper function Ft (to compute z = z \* u).
|
||||
|
||||
::
|
||||
|
||||
u k z Ft
|
||||
---------------
|
||||
u k u*z
|
||||
u k z Ft
|
||||
---------------
|
||||
u k u*z
|
||||
|
||||
|
||||
Ft == [over] dip *
|
||||
Ft == [over] dip *
|
||||
|
||||
Putting it together:
|
||||
|
||||
::
|
||||
|
||||
Ft == [over] dip *
|
||||
Fb == [[sqr] dip 2 //] dip
|
||||
Fw == [pop odd] [Ft] [] ifte Fb
|
||||
F == 1 [pop] [Fw] while popopd
|
||||
Ft == [over] dip *
|
||||
Fb == [[sqr] dip 2 //] dip
|
||||
Fw == [pop odd] [Ft] [] ifte Fb
|
||||
F == 1 [pop] [Fw] while popopd
|
||||
|
||||
.. code:: ipython2
|
||||
|
||||
|
|
@ -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 let’s 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.
|
||||
Let’s try partial evaluation by hand and use a “stronger” thunk.
|
||||
|
||||
Caret underscoring indicates terms that form thunks. When an arg is
|
||||
unavailable for a computation we just postpone it until the arg becomes
|
||||
|
|
@ -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
|
||||
I’m not sure how to implement these kinds of thunks. I think you have to
|
||||
have support in the interpreter, or you have to modify all of the
|
||||
functions like ``dup`` to check for thunks in their inputs.
|
||||
|
||||
|
|
@ -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 doesn’t seem easy to
|
||||
directly apply this technique to Joy code:
|
||||
|
||||
::
|
||||
|
||||
Ft == [over] dip *
|
||||
Fb == [[sqr] dip 2 //] dip
|
||||
Fw == [pop odd] [Ft] [] ifte Fb
|
||||
F == 1 [pop] [Fw] while popopd
|
||||
Ft == [over] dip *
|
||||
Fb == [[sqr] dip 2 //] dip
|
||||
Fw == [pop odd] [Ft] [] ifte Fb
|
||||
F == 1 [pop] [Fw] while popopd
|
||||
|
||||
But a direct translation of the Python code..?
|
||||
|
||||
::
|
||||
|
||||
F == [
|
||||
[[0 =] [pop 1]]
|
||||
[[1 =] []]
|
||||
[_F.0]
|
||||
] cond
|
||||
F == [
|
||||
[[0 =] [pop 1]]
|
||||
[[1 =] []]
|
||||
[_F.0]
|
||||
] cond
|
||||
|
||||
_F.0 == dup 2 // [
|
||||
[[0 =] [pop 1]]
|
||||
[[pop odd] _F.1]
|
||||
[_F.2]
|
||||
] cond
|
||||
_F.0 == dup 2 // [
|
||||
[[0 =] [pop 1]]
|
||||
[[pop odd] _F.1]
|
||||
[_F.2]
|
||||
] cond
|
||||
|
||||
_F.1 == [1 =] [pop [dup dup * *]] [popd F [dupdip over * *] cons] ifte
|
||||
_F.2 == [1 =] [pop [dup *]] [popd F [i dup *] cons] ifte
|
||||
_F.1 == [1 =] [pop [dup dup * *]] [popd F [dupdip over * *] cons] ifte
|
||||
_F.2 == [1 =] [pop [dup *]] [popd F [i dup *] cons] ifte
|
||||
|
||||
Try it:
|
||||
|
||||
::
|
||||
|
||||
5 F
|
||||
5 [ [[0 =] [pop 1]] [[1 =] []] [_F.0] ] cond
|
||||
5 _F.0
|
||||
5 dup 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
5 5 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
5 F
|
||||
5 [ [[0 =] [pop 1]] [[1 =] []] [_F.0] ] cond
|
||||
5 _F.0
|
||||
5 dup 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
5 5 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
|
||||
5 2 [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
5 2 _F.1
|
||||
5 2 [1 =] [popop [dup dup * *]] [popd F [dupdip over * *] cons] ifte
|
||||
5 2 popd F [dupdip over * *] cons
|
||||
2 F [dupdip over * *] cons
|
||||
5 2 [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
5 2 _F.1
|
||||
5 2 [1 =] [popop [dup dup * *]] [popd F [dupdip over * *] cons] ifte
|
||||
5 2 popd F [dupdip over * *] cons
|
||||
2 F [dupdip over * *] cons
|
||||
|
||||
2 F [dupdip over * *] cons
|
||||
2 F [dupdip over * *] cons
|
||||
|
||||
2 F
|
||||
2 [ [[0 =] [pop 1]] [[1 =] []] [_F.0] ] cond
|
||||
2 _F.0
|
||||
2 dup 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
2 2 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
2 1 [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
2 1 _F.2
|
||||
2 1 [1 =] [popop [dup *]] [popd F [i dup *] cons] ifte
|
||||
2 1 popop [dup *]
|
||||
[dup *]
|
||||
2 F
|
||||
2 [ [[0 =] [pop 1]] [[1 =] []] [_F.0] ] cond
|
||||
2 _F.0
|
||||
2 dup 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
2 2 2 // [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
2 1 [ [[0 =] [pop 1]] [[pop odd] _F.1] [_F.2] ] cond
|
||||
2 1 _F.2
|
||||
2 1 [1 =] [popop [dup *]] [popd F [i dup *] cons] ifte
|
||||
2 1 popop [dup *]
|
||||
[dup *]
|
||||
|
||||
|
||||
2 F [dupdip over * *] cons
|
||||
[dup *] [dupdip over * *] cons
|
||||
[[dup *] dupdip over * *]
|
||||
2 F [dupdip over * *] cons
|
||||
[dup *] [dupdip over * *] cons
|
||||
[[dup *] dupdip over * *]
|
||||
|
||||
And here it is in action:
|
||||
|
||||
::
|
||||
|
||||
2 [[dup *] dupdip over * *] i
|
||||
2 [dup *] dupdip over * *
|
||||
2 dup * 2 over * *
|
||||
2 2 * 2 over * *
|
||||
4 2 over * *
|
||||
4 2 4 * *
|
||||
4 8 *
|
||||
32
|
||||
2 [[dup *] dupdip over * *] i
|
||||
2 [dup *] dupdip over * *
|
||||
2 dup * 2 over * *
|
||||
2 2 * 2 over * *
|
||||
4 2 over * *
|
||||
4 2 4 * *
|
||||
4 8 *
|
||||
32
|
||||
|
||||
So, it works, but in this case the results of the partial evaluation are
|
||||
more elegant.
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Reference in New Issue