diff --git a/docs/Types.html b/docs/Types.html index a6f1526..ad4e69a 100644 --- a/docs/Types.html +++ b/docs/Types.html @@ -11775,7 +11775,11 @@ div#notebook {
-

Type Inference

Cf. "Type Inference in Stack-Based Programming Languages" by Rob Kleffner, 2017-03-10.

+

Type Inference

This notebook presents a simple type inferencer for Joy code. It can infer the stack effect of most Joy expressions. It built largely by means of existing ideas and research (some of it may be original but I'm not able to say, as I don't fully understand the all of the source material in the depth required to make that call.) A great overview of the existing knowledge is a talk "Type Inference in Stack-Based Programming Languages" given by Rob Kleffner on or about 2017-03-10 as part of a course on the history of programming languages.

+

The notebook starts with a simple inferencer based on the work of Jaanus Pöial which we then progressively elaborate to cover more Joy semantics. Along the way we write a simple "compiler" that emits Python code for what I like to call Yin functions.

+

Yin functions are those that only rearrange values in stacks, as opposed to Yang functions that actually work on the values themselves. It's interesting to note that a Joy with only stacks (no other kinds of values) can be made and is Turing-complete, therefore all Yang functions are actually Yin functions, and all computation can be performed by manipulations of structures of containers, which is a restatement of the Laws of Form. (Also, this implies that every program can be put into a form such that it can be computed in a single step, although that step may be enormous or unending.)

+

Although I haven't completed it yet, a Joy based on Laws of Form provides the foundation for a provably correct computing system "down to the metal". This is my original and still primary motivation for developing Joy. (I want a proven-correct Operating System for a swarm of trash-collecting recycler robots. To trust it I have to implementment it myself from first principles, and I'm not smart enough to truly grok the existing literature and software, so I had to go look for and find LoF and Joy. Now that I have the mental tools to build my robot OS I can get down to it.

+

Anyhow, here's type inference...

@@ -12953,7 +12957,7 @@ cons ( 1 [...] -- [1 ...] )
-

Part III: Compiling Stack Functions

Now consider the Python function we would like to derive:

+

Part III: Compiling Yin Functions

Now consider the Python function we would like to derive:

@@ -14409,7 +14413,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
In [57]:
-
# e.g. [popop] dip
+
# e.g. [popop] dipd
 neato(popdd, roll_down, pop)
 
@@ -14578,6 +14582,15 @@ uncons = ([a1 .1.] -- a1 [.1.])
+
+
+
+
+
+

(Eventually I should come back around to this becuase it's not tooo difficult to exend this code to be able to compile e.g. n3 = mul(n1, n2) for mul and insert it in the right place with the right variable names. It requires a little more support from the library functions, in that we need to know to call mul() the Python function for mul the Joy function, but since most of the math functions (at least) are already wrappers it should be straightforward.)

+ +
+
@@ -15627,7 +15640,7 @@ uncons = ([a1 .1.] -- a1 [.1.]) w/ {d: e} [ A* b .0.] U [ .1.] w/ {.1.: A* b .0.} -[ A* b .0.] U [ .1.] +[ A* b .0.] U [ A* b .0.]
@@ -16362,22 +16375,16 @@ uncons = ([a1 .1.] -- a1 [.1.])
-

Part VII: Typing Combinators

TBD

-

This is an open subject.

-

The obvious thing is that you now need two pairs of tuples to describe the combinators' effects, a stack effect comment and an expression effect comment:

+

Part VII: Typing Combinators

In order to compute the stack effect of combinators you kinda have to have the quoted programs they expect available. In the most general case, the i combinator, you can't say anything about it's stack effect other than it expects one quote:

-
dip (a [F] --)--(-- F a)
+
i (... [.1.] -- ... .1.)
 
 
-

One thing that might help is...

+

Or

-
-
- -
-
-
-
+
i (... [A* .1.] -- ... A*)
+
+

Consider the type of:

[cons] dip
@@ -16390,7 +16397,20 @@ uncons = ([a1 .1.] -- a1 [.1.])
 

dip itself could have:

-
(a1 [..1] -- ... then what?
+
(a1 [..1] -- ... then what?
+
+
+
+

Without any information about the contents of the quote we can't say much about the result.

+ +
+
+
+
+
+
+
+

I think there's a way forward. If we convert our list of terms we are composing into a stack structure we can use it as a Joy expression, then we can treat the output half of a function's stack effect comment as a Joy interpreter stack, and just execute combinators directly. We can hybridize the compostition function with an interpreter to evaluate combinators, compose non-combinator functions, and put type variables on the stack. For combinators like branch that can have more than one stack effect we have to "split universes" again and return both. (Note: bug! If one branch doesn't type check the currect code ignores it, so you can think things are okay but have a type error waiting in the faled branch, I think... D'oh! FIXME!!!)

@@ -16398,567 +16418,6 @@ uncons = ([a1 .1.] -- a1 [.1.])
In [108]:
-
-
-
class SymbolJoyType(AnyJoyType): prefix = 'F'
-
-W = map(SymbolJoyType, _R)
-
-k = S[0], ((W[1], S[2]), S[0])
-Symbol('cons')
-print doc_from_stack_effect(*k)
-
- -
-
-
- -
-
- - -
- -
- - -
-
(-- [F1 .2.])
-
-
-
- -
-
- -
-
-
-
In [109]:
-
-
-
dip_a = ((W[1], S[2]), (A[1], S[0]))
-
- -
-
-
- -
-
-
-
In [110]:
-
-
-
d = relabel(S[0], dip_a)
-print doc_from_stack_effect(*d)
-
- -
-
-
- -
-
- - -
- -
- - -
-
(-- a1001 [F1001 .1002.])
-
-
-
- -
-
- -
-
-
-
In [111]:
-
-
-
s = list(unify(d[1], k[1]))[0]
-s
-
- -
-
-
- -
-
- - -
- -
Out[111]:
- - - - -
-
{s0: (a1001, s1000), s1002: s2, F1001: F1}
-
- -
- -
-
- -
-
-
-
In [112]:
-
-
-
j = update(s, k)
-
- -
-
-
- -
-
-
-
In [113]:
-
-
-
print doc_from_stack_effect(*j)
-
- -
-
-
- -
-
- - -
- -
- - -
-
(a1001 -- a1001 [F1 .2.])
-
-
-
- -
-
- -
-
-
-
In [114]:
-
-
-
j
-
- -
-
-
- -
-
- - -
- -
Out[114]:
- - - - -
-
((a1001, s1000), ((F1, s2), (a1001, s1000)))
-
- -
- -
-
- -
-
-
-
In [115]:
-
-
-
cons
-
- -
-
-
- -
-
- - -
- -
Out[115]:
- - - - -
-
((s1, (a1, s23)), ((a1, s1), s23))
-
- -
- -
-
- -
-
-
-
In [116]:
-
-
-
for f in MC([k], [dup]):
-    print doc_from_stack_effect(*f)
-
- -
-
-
- -
-
- - -
- -
- - -
-
(-- [F0 .1.] [F0 .1.])
-
-
-
- -
-
- -
-
-
-
In [117]:
-
-
-
l = S[0], ((cons, S[2]), (A[1], S[0]))
-
- -
-
-
- -
-
-
-
In [118]:
-
-
-
print doc_from_stack_effect(*l)
-
- -
-
-
- -
-
- - -
- -
- - -
-
(-- a1 [[[[.1.] a1 .23.] [a1 .1.] .23.] .2.])
-
-
-
- -
-
- -
-
-
-
In [119]:
-
-
-
def dip_t(F):
-    (quote, (a1, sec)) = F[1]
-    G = F[0], sec
-    P = S[3], (a1, S[3])
-    a = [P]
-    while isinstance(quote, tuple):
-        term, quote = quote
-        a.append(term)
-    a.append(G)
-    return a[::-1]
-
- -
-
-
- -
-
-
-
In [120]:
-
-
-
from joy.utils.stack import iter_stack
-
- -
-
-
- -
-
-
-
In [121]:
-
-
-
a, b, c = dip_t(l)
-
- -
-
-
- -
-
-
-
In [122]:
-
-
-
a
-
- -
-
-
- -
-
- - -
- -
Out[122]:
- - - - -
-
(s0, s0)
-
- -
- -
-
- -
-
-
-
In [123]:
-
-
-
b
-
- -
-
-
- -
-
- - -
- -
Out[123]:
- - - - -
-
((s1, (a1, s23)), ((a1, s1), s23))
-
- -
- -
-
- -
-
-
-
In [124]:
-
-
-
c
-
- -
-
-
- -
-
- - -
- -
Out[124]:
- - - - -
-
(s3, (a1, s3))
-
- -
- -
-
- -
-
-
-
In [125]:
-
-
-
MC([a], [b])
-
- -
-
-
- -
-
- - -
- -
Out[125]:
- - - - -
-
[((s0, (a0, s1)), ((a0, s0), s1))]
-
- -
- -
-
- -
-
-
-
In [126]:
-
-
-
kjs = MC(MC([a], [b]), [c])
-kjs
-
- -
-
-
- -
-
- - -
- -
Out[126]:
- - - - -
-
[((s0, (a0, s1)), (a1, ((a0, s0), s1)))]
-
- -
- -
-
- -
-
-
-
In [127]:
-
-
-
print doc_from_stack_effect(*kjs[0])
-
- -
-
-
- -
-
- - -
- -
- - -
-
(a0 [.0.] -- [a0 .0.] a1)
-
-
-
- -
-
- -
-
-
-
-
- -
(a0 [.0.] -- [a0 .0.] a1)
-
-   a0 [.0.] a1 [cons] dip
-----------------------------
-   [a0 .0.] a1
- -
-
-
-
-
-
In [128]:
stack_concat = lambda q, e: (q[0], stack_concat(q[1], e)) if q else e
@@ -16971,7 +16430,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
-
In [129]:
+
In [109]:
class SymbolJoyType(AnyJoyType):
@@ -17030,7 +16489,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
-
In [130]:
+
In [110]:
def dip_t(stack, expression):
@@ -17046,7 +16505,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
-
In [131]:
+
In [111]:
def dip(stack, expression, dictionary):
@@ -17077,194 +16536,6 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
-
-
-
-
-
-

concat

How to deal with concat?

- -
concat ([.0.] [.1.] -- [.0. .1.])
-
-
-

We would like to represent this in Python somehow...

- -
-
-
-
-
-
In [132]:
-
-
-
concat = (S[0], S[1]), ((S[0], S[1]),)
-
- -
-
-
- -
-
-
-
-
-

But this is actually cons with the first argument restricted to be a stack:

- -
([.0.] [.1.] -- [[.0.] .1.])
-
-
-

What we have implemented so far would actually only permit:

- -
([.0.] [.1.] -- [.2.])
- -
-
-
-
-
-
In [133]:
-
-
-
concat = (S[0], S[1]), (S[2],)
-
- -
-
-
- -
-
-
-
-
-

Which works but can lose information. Consider cons concat, this is how much information we could retain:

- -
(1 [.0.] [.1.] -- [1 .0. .1.])
-
-
-

As opposed to just:

- -
(1 [.0.] [.1.] -- [.2.])
- -
-
-
-
-
-
-
-

represent concat

-
([.0.] [.1.] -- [A*(.0.) .1.])
-
-
-

Meaning that A* on the right-hand side should all the crap from .0..

- -
([      .0.] [.1.] -- [      A* .1.])
-([a     .0.] [.1.] -- [a     A* .1.])
-([a b   .0.] [.1.] -- [a b   A* .1.])
-([a b c .0.] [.1.] -- [a b c A* .1.])
- -
-
-
-
-
-
-
-

or...

- -
([       .0.] [.1.] -- [       .1.])
-([a      .0.] [.1.] -- [a      .1.])
-([a b    .0.] [.1.] -- [a b    .1.])
-([a b  c .0.] [.1.] -- [a b  c .1.])
-([a A* c .0.] [.1.] -- [a A* c .1.])
- -
-
-
-
-
-
-
- -
(a, (b, S0)) . S1 = (a, (b, (A*, S1)))
- -
-
-
-
-
-
In [134]:
-
-
-
class Astar(object):
-    def __repr__(self):
-        return 'A*'
-
-
-def concat(s0, s1):
-    a = []
-    while isinstance(s0, tuple):
-        term, s0 = s0
-        a.append(term)
-    assert isinstance(s0, StackJoyType), repr(s0)
-    s1 = Astar(), s1
-    for term in reversed(a):
-        s1 = term, s1
-    return s1
-
- -
-
-
- -
-
-
-
In [135]:
-
-
-
a, b = (A[1], S[0]), (A[2], S[1])
-
- -
-
-
- -
-
-
-
In [136]:
-
-
-
concat(a, b)
-
- -
-
-
- -
-
- - -
- -
Out[136]:
- - - - -
-
(a1, (A*, (a2, s1)))
-
- -
- -
-
-
@@ -17277,7 +16548,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
-
In [137]:
+
In [112]:
F = reduce(C, (pop, swap, roll_down, rest, rest, cons, cons))
@@ -17302,7 +16573,7 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 ---------------------------------------------------------------------------
 ValueError                                Traceback (most recent call last)
-<ipython-input-137-4b4cb6ff86e5> in <module>()
+<ipython-input-112-4b4cb6ff86e5> in <module>()
       1 F = reduce(C, (pop, swap, roll_down, rest, rest, cons, cons))
       2 
 ----> 3 print doc_from_stack_effect(*F)
@@ -17469,6 +16740,475 @@ uncons = ([a1 .1.] -- a1 [.1.])
 
 
+
+
+
+
+
+

Junk

+
+
+
+
+
+
In [ ]:
+
+
+
class SymbolJoyType(AnyJoyType): prefix = 'F'
+
+W = map(SymbolJoyType, _R)
+
+k = S[0], ((W[1], S[2]), S[0])
+Symbol('cons')
+print doc_from_stack_effect(*k)
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
dip_a = ((W[1], S[2]), (A[1], S[0]))
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
d = relabel(S[0], dip_a)
+print doc_from_stack_effect(*d)
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
s = list(unify(d[1], k[1]))[0]
+s
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
j = update(s, k)
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
print doc_from_stack_effect(*j)
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
j
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
cons
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
for f in MC([k], [dup]):
+    print doc_from_stack_effect(*f)
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
l = S[0], ((cons, S[2]), (A[1], S[0]))
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
print doc_from_stack_effect(*l)
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
def dip_t(F):
+    (quote, (a1, sec)) = F[1]
+    G = F[0], sec
+    P = S[3], (a1, S[3])
+    a = [P]
+    while isinstance(quote, tuple):
+        term, quote = quote
+        a.append(term)
+    a.append(G)
+    return a[::-1]
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
from joy.utils.stack import iter_stack
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
a, b, c = dip_t(l)
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
a
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
b
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
c
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
MC([a], [b])
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
kjs = MC(MC([a], [b]), [c])
+kjs
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
print doc_from_stack_effect(*kjs[0])
+
+ +
+
+
+ +
+
+
+
+
+ +
(a0 [.0.] -- [a0 .0.] a1)
+
+   a0 [.0.] a1 [cons] dip
+----------------------------
+   [a0 .0.] a1
+ +
+
+
+
+
+
+
+

concat

How to deal with concat?

+ +
concat ([.0.] [.1.] -- [.0. .1.])
+
+
+

We would like to represent this in Python somehow...

+ +
+
+
+
+
+
In [ ]:
+
+
+
concat = (S[0], S[1]), ((S[0], S[1]),)
+
+ +
+
+
+ +
+
+
+
+
+

But this is actually cons with the first argument restricted to be a stack:

+ +
([.0.] [.1.] -- [[.0.] .1.])
+
+
+

What we have implemented so far would actually only permit:

+ +
([.0.] [.1.] -- [.2.])
+ +
+
+
+
+
+
In [ ]:
+
+
+
concat = (S[0], S[1]), (S[2],)
+
+ +
+
+
+ +
+
+
+
+
+

Which works but can lose information. Consider cons concat, this is how much information we could retain:

+ +
(1 [.0.] [.1.] -- [1 .0. .1.])
+
+
+

As opposed to just:

+ +
(1 [.0.] [.1.] -- [.2.])
+ +
+
+
+
+
+
+
+

represent concat

+
([.0.] [.1.] -- [A*(.0.) .1.])
+
+
+

Meaning that A* on the right-hand side should all the crap from .0..

+ +
([      .0.] [.1.] -- [      A* .1.])
+([a     .0.] [.1.] -- [a     A* .1.])
+([a b   .0.] [.1.] -- [a b   A* .1.])
+([a b c .0.] [.1.] -- [a b c A* .1.])
+ +
+
+
+
+
+
+
+

or...

+ +
([       .0.] [.1.] -- [       .1.])
+([a      .0.] [.1.] -- [a      .1.])
+([a b    .0.] [.1.] -- [a b    .1.])
+([a b  c .0.] [.1.] -- [a b  c .1.])
+([a A* c .0.] [.1.] -- [a A* c .1.])
+ +
+
+
+
+
+
+
+ +
(a, (b, S0)) . S1 = (a, (b, (A*, S1)))
+ +
+
+
+
+
+
In [ ]:
+
+
+
class Astar(object):
+    def __repr__(self):
+        return 'A*'
+
+
+def concat(s0, s1):
+    a = []
+    while isinstance(s0, tuple):
+        term, s0 = s0
+        a.append(term)
+    assert isinstance(s0, StackJoyType), repr(s0)
+    s1 = Astar(), s1
+    for term in reversed(a):
+        s1 = term, s1
+    return s1
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
a, b = (A[1], S[0]), (A[2], S[1])
+
+ +
+
+
+ +
+
+
+
In [ ]:
+
+
+
concat(a, b)
+
+ +
+
+
+
diff --git a/docs/Types.ipynb b/docs/Types.ipynb index 2f9ddf1..d72550e 100644 --- a/docs/Types.ipynb +++ b/docs/Types.ipynb @@ -6,7 +6,15 @@ "source": [ "# Type Inference\n", "\n", - "Cf. [\"Type Inference in Stack-Based Programming Languages\"](http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/) by Rob Kleffner, 2017-03-10." + "This notebook presents a simple type inferencer for Joy code. It can infer the stack effect of most Joy expressions. It built largely by means of existing ideas and research (some of it may be original but I'm not able to say, as I don't fully understand the all of the source material in the depth required to make that call.) A great overview of the existing knowledge is a talk [\"Type Inference in Stack-Based Programming Languages\"](http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/) given by Rob Kleffner on or about 2017-03-10 as part of a course on the history of programming languages.\n", + "\n", + "The notebook starts with a simple inferencer based on the work of Jaanus Pöial which we then progressively elaborate to cover more Joy semantics. Along the way we write a simple \"compiler\" that emits Python code for what I like to call Yin functions.\n", + "\n", + "Yin functions are those that only rearrange values in stacks, as opposed to Yang functions that actually work on the values themselves. It's interesting to note that a Joy with *only* stacks (no other kinds of values) can be made and is Turing-complete, therefore all Yang functions are actually Yin functions, and all computation can be performed by manipulations of structures of containers, which is a restatement of the Laws of Form. (Also, this implies that every program can be put into a form such that it can be computed in a single step, although that step may be enormous or unending.)\n", + "\n", + "Although I haven't completed it yet, a Joy based on Laws of Form provides the foundation for a provably correct computing system \"down to the metal\". This is my original and still primary motivation for developing Joy. (I want a proven-correct Operating System for a swarm of trash-collecting recycler robots. To trust it I have to implementment it myself from first principles, and I'm not smart enough to truly grok the existing literature and software, so I had to go look for and find LoF and Joy. Now that I have the mental tools to build my robot OS I can get down to it.\n", + "\n", + "Anyhow, here's type inference..." ] }, { @@ -926,7 +934,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Part III: Compiling Stack Functions\n", + "## Part III: Compiling Yin Functions\n", "Now consider the Python function we would like to derive:" ] }, @@ -2047,7 +2055,7 @@ } ], "source": [ - "# e.g. [popop] dip\n", + "# e.g. [popop] dipd\n", "neato(popdd, roll_down, pop)" ] }, @@ -2145,6 +2153,13 @@ "print compile_('sqr', C(dup, mul))" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(Eventually I should come back around to this becuase it's not tooo difficult to exend this code to be able to compile e.g. `n3 = mul(n1, n2)` for `mul` and insert it in the right place with the right variable names. It requires a little more support from the library functions, in that we need to know to call `mul()` the Python function for `mul` the Joy function, but since *most* of the math functions (at least) are already wrappers it should be straightforward.)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -3575,28 +3590,14 @@ "source": [ "## Part VII: Typing Combinators\n", "\n", - "TBD\n", + "In order to compute the stack effect of combinators you kinda have to have the quoted programs they expect available. In the most general case, the `i` combinator, you can't say anything about it's stack effect other than it expects one quote:\n", "\n", - "This is an open subject.\n", + " i (... [.1.] -- ... .1.)\n", "\n", - "The obvious thing is that you now need two pairs of tuples to describe the combinators' effects, a stack effect comment and an expression effect comment:\n", + "Or\n", "\n", - " dip (a [F] --)--(-- F a)\n", + " i (... [A* .1.] -- ... A*)\n", "\n", - "One thing that might help is..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ "Consider the type of:\n", "\n", " [cons] dip\n", @@ -3607,146 +3608,10 @@ "\n", "`dip` itself could have:\n", "\n", - " (a1 [..1] -- ... then what?\n" - ] - }, - { - "cell_type": "code", - "execution_count": 108, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(-- [F1 .2.])\n" - ] - } - ], - "source": [ - "class SymbolJoyType(AnyJoyType): prefix = 'F'\n", + " (a1 [..1] -- ... then what?\n", "\n", - "W = map(SymbolJoyType, _R)\n", "\n", - "k = S[0], ((W[1], S[2]), S[0])\n", - "Symbol('cons')\n", - "print doc_from_stack_effect(*k)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 109, - "metadata": {}, - "outputs": [], - "source": [ - "dip_a = ((W[1], S[2]), (A[1], S[0]))" - ] - }, - { - "cell_type": "code", - "execution_count": 110, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(-- a1001 [F1001 .1002.])\n" - ] - } - ], - "source": [ - "d = relabel(S[0], dip_a)\n", - "print doc_from_stack_effect(*d)" - ] - }, - { - "cell_type": "code", - "execution_count": 111, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{s0: (a1001, s1000), s1002: s2, F1001: F1}" - ] - }, - "execution_count": 111, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s = list(unify(d[1], k[1]))[0]\n", - "s" - ] - }, - { - "cell_type": "code", - "execution_count": 112, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "j = update(s, k)" - ] - }, - { - "cell_type": "code", - "execution_count": 113, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(a1001 -- a1001 [F1 .2.])\n" - ] - } - ], - "source": [ - "print doc_from_stack_effect(*j)" - ] - }, - { - "cell_type": "code", - "execution_count": 114, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((a1001, s1000), ((F1, s2), (a1001, s1000)))" - ] - }, - "execution_count": 114, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "j" - ] - }, - { - "cell_type": "code", - "execution_count": 115, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((s1, (a1, s23)), ((a1, s1), s23))" - ] - }, - "execution_count": 115, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cons" + "Without any information about the contents of the quote we can't say much about the result." ] }, { @@ -3756,252 +3621,16 @@ "outputs": [], "source": [] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 116, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(-- [F0 .1.] [F0 .1.])\n" - ] - } - ], - "source": [ - "for f in MC([k], [dup]):\n", - " print doc_from_stack_effect(*f)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 117, - "metadata": {}, - "outputs": [], - "source": [ - "l = S[0], ((cons, S[2]), (A[1], S[0]))" - ] - }, - { - "cell_type": "code", - "execution_count": 118, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(-- a1 [[[[.1.] a1 .23.] [a1 .1.] .23.] .2.])\n" - ] - } - ], - "source": [ - "print doc_from_stack_effect(*l)" - ] - }, - { - "cell_type": "code", - "execution_count": 119, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "def dip_t(F):\n", - " (quote, (a1, sec)) = F[1]\n", - " G = F[0], sec\n", - " P = S[3], (a1, S[3])\n", - " a = [P]\n", - " while isinstance(quote, tuple):\n", - " term, quote = quote\n", - " a.append(term)\n", - " a.append(G)\n", - " return a[::-1]\n", - "\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 120, - "metadata": {}, - "outputs": [], - "source": [ - "from joy.utils.stack import iter_stack" - ] - }, - { - "cell_type": "code", - "execution_count": 121, - "metadata": {}, - "outputs": [], - "source": [ - "a, b, c = dip_t(l)" - ] - }, - { - "cell_type": "code", - "execution_count": 122, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(s0, s0)" - ] - }, - "execution_count": 122, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a" - ] - }, - { - "cell_type": "code", - "execution_count": 123, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "((s1, (a1, s23)), ((a1, s1), s23))" - ] - }, - "execution_count": 123, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "b" - ] - }, - { - "cell_type": "code", - "execution_count": 124, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(s3, (a1, s3))" - ] - }, - "execution_count": 124, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "c" - ] - }, - { - "cell_type": "code", - "execution_count": 125, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[((s0, (a0, s1)), ((a0, s0), s1))]" - ] - }, - "execution_count": 125, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "MC([a], [b])" - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[((s0, (a0, s1)), (a1, ((a0, s0), s1)))]" - ] - }, - "execution_count": 126, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "kjs = MC(MC([a], [b]), [c])\n", - "kjs" - ] - }, - { - "cell_type": "code", - "execution_count": 127, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(a0 [.0.] -- [a0 .0.] a1)\n" - ] - } - ], - "source": [ - "print doc_from_stack_effect(*kjs[0])" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - " (a0 [.0.] -- [a0 .0.] a1)\n", - " \n", - " a0 [.0.] a1 [cons] dip\n", - " ----------------------------\n", - " [a0 .0.] a1" + "I think there's a way forward. If we convert our list of terms we are composing into a stack structure we can use it as a *Joy expression*, then we can treat the *output half* of a function's stack effect comment as a Joy interpreter stack, and just execute combinators directly. We can hybridize the compostition function with an interpreter to evaluate combinators, compose non-combinator functions, and put type variables on the stack. For combinators like `branch` that can have more than one stack effect we have to \"split universes\" again and return both. (Note: bug! If one branch doesn't type check the currect code ignores it, so you can think things are okay but have a type error waiting in the faled branch, I think... D'oh! FIXME!!!)" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 128, + "execution_count": 108, "metadata": {}, "outputs": [], "source": [ @@ -4010,7 +3639,7 @@ }, { "cell_type": "code", - "execution_count": 129, + "execution_count": 109, "metadata": {}, "outputs": [], "source": [ @@ -4077,7 +3706,7 @@ }, { "cell_type": "code", - "execution_count": 130, + "execution_count": 110, "metadata": {}, "outputs": [], "source": [ @@ -4089,7 +3718,7 @@ }, { "cell_type": "code", - "execution_count": 131, + "execution_count": 111, "metadata": {}, "outputs": [], "source": [ @@ -4106,6 +3735,125 @@ "outputs": [], "source": [] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "metadata": {}, @@ -4120,175 +3868,6 @@ "The rest of this stuff is junk and/or unfinished material." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### `concat`\n", - "\n", - "How to deal with `concat`?\n", - "\n", - " concat ([.0.] [.1.] -- [.0. .1.])\n", - " \n", - "We would like to represent this in Python somehow..." - ] - }, - { - "cell_type": "code", - "execution_count": 132, - "metadata": {}, - "outputs": [], - "source": [ - "concat = (S[0], S[1]), ((S[0], S[1]),)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But this is actually `cons` with the first argument restricted to be a stack:\n", - "\n", - " ([.0.] [.1.] -- [[.0.] .1.])\n", - "\n", - "What we have implemented so far would actually only permit:\n", - "\n", - " ([.0.] [.1.] -- [.2.])" - ] - }, - { - "cell_type": "code", - "execution_count": 133, - "metadata": {}, - "outputs": [], - "source": [ - "concat = (S[0], S[1]), (S[2],)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " \n", - "Which works but can lose information. Consider `cons concat`, this is how much information we *could* retain:\n", - "\n", - " (1 [.0.] [.1.] -- [1 .0. .1.])\n", - "\n", - "As opposed to just:\n", - "\n", - " (1 [.0.] [.1.] -- [.2.])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### represent `concat`\n", - "\n", - " ([.0.] [.1.] -- [A*(.0.) .1.])\n", - "\n", - "Meaning that `A*` on the right-hand side should all the crap from `.0.`.\n", - "\n", - " ([ .0.] [.1.] -- [ A* .1.])\n", - " ([a .0.] [.1.] -- [a A* .1.])\n", - " ([a b .0.] [.1.] -- [a b A* .1.])\n", - " ([a b c .0.] [.1.] -- [a b c A* .1.])\n", - "\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "or...\n", - "\n", - " ([ .0.] [.1.] -- [ .1.])\n", - " ([a .0.] [.1.] -- [a .1.])\n", - " ([a b .0.] [.1.] -- [a b .1.])\n", - " ([a b c .0.] [.1.] -- [a b c .1.])\n", - " ([a A* c .0.] [.1.] -- [a A* c .1.])\n", - "\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " (a, (b, S0)) . S1 = (a, (b, (A*, S1)))" - ] - }, - { - "cell_type": "code", - "execution_count": 134, - "metadata": {}, - "outputs": [], - "source": [ - "class Astar(object):\n", - " def __repr__(self):\n", - " return 'A*'\n", - "\n", - "\n", - "def concat(s0, s1):\n", - " a = []\n", - " while isinstance(s0, tuple):\n", - " term, s0 = s0\n", - " a.append(term)\n", - " assert isinstance(s0, StackJoyType), repr(s0)\n", - " s1 = Astar(), s1\n", - " for term in reversed(a):\n", - " s1 = term, s1\n", - " return s1" - ] - }, - { - "cell_type": "code", - "execution_count": 135, - "metadata": {}, - "outputs": [], - "source": [ - "a, b = (A[1], S[0]), (A[2], S[1])" - ] - }, - { - "cell_type": "code", - "execution_count": 136, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(a1, (A*, (a2, s1)))" - ] - }, - "execution_count": 136, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "concat(a, b)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "metadata": {}, @@ -4299,7 +3878,7 @@ }, { "cell_type": "code", - "execution_count": 137, + "execution_count": 112, "metadata": {}, "outputs": [ { @@ -4309,7 +3888,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mF\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mreduce\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mC\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mswap\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mroll_down\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcons\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcons\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0mdoc_from_stack_effect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mF\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mF\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mreduce\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mC\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mswap\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mroll_down\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrest\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcons\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcons\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0mdoc_from_stack_effect\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mF\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mC\u001b[0;34m(f, g)\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mC\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrelabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mfg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcompose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m \u001b[0;32myield\u001b[0m \u001b[0mdelabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mcompose\u001b[0;34m(f, g)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcompose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;34m(\u001b[0m\u001b[0mf_in\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf_out\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mg_in\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg_out\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0ms\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0munify\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mg_in\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf_out\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Cannot unify %r and %r.'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mf_out\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg_in\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mC\u001b[0;34m(f, g)\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mC\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrelabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mfg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcompose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 13\u001b[0m \u001b[0;32myield\u001b[0m \u001b[0mdelabel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", @@ -4409,6 +3988,424 @@ " In any event \"mixed-mode\" interpreters that include values and type variables and can track constraints, etc. will be, uh, super-useful. And Abstract Interpretation should be a rich source of ideas.\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Junk" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class SymbolJoyType(AnyJoyType): prefix = 'F'\n", + "\n", + "W = map(SymbolJoyType, _R)\n", + "\n", + "k = S[0], ((W[1], S[2]), S[0])\n", + "Symbol('cons')\n", + "print doc_from_stack_effect(*k)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dip_a = ((W[1], S[2]), (A[1], S[0]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "d = relabel(S[0], dip_a)\n", + "print doc_from_stack_effect(*d)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "s = list(unify(d[1], k[1]))[0]\n", + "s" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "j = update(s, k)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print doc_from_stack_effect(*j)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "j" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cons" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "for f in MC([k], [dup]):\n", + " print doc_from_stack_effect(*f)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "l = S[0], ((cons, S[2]), (A[1], S[0]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print doc_from_stack_effect(*l)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def dip_t(F):\n", + " (quote, (a1, sec)) = F[1]\n", + " G = F[0], sec\n", + " P = S[3], (a1, S[3])\n", + " a = [P]\n", + " while isinstance(quote, tuple):\n", + " term, quote = quote\n", + " a.append(term)\n", + " a.append(G)\n", + " return a[::-1]\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from joy.utils.stack import iter_stack" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a, b, c = dip_t(l)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "b" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "c" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "MC([a], [b])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "kjs = MC(MC([a], [b]), [c])\n", + "kjs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print doc_from_stack_effect(*kjs[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " (a0 [.0.] -- [a0 .0.] a1)\n", + " \n", + " a0 [.0.] a1 [cons] dip\n", + " ----------------------------\n", + " [a0 .0.] a1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### `concat`\n", + "\n", + "How to deal with `concat`?\n", + "\n", + " concat ([.0.] [.1.] -- [.0. .1.])\n", + " \n", + "We would like to represent this in Python somehow..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "concat = (S[0], S[1]), ((S[0], S[1]),)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "But this is actually `cons` with the first argument restricted to be a stack:\n", + "\n", + " ([.0.] [.1.] -- [[.0.] .1.])\n", + "\n", + "What we have implemented so far would actually only permit:\n", + "\n", + " ([.0.] [.1.] -- [.2.])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "concat = (S[0], S[1]), (S[2],)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " \n", + "Which works but can lose information. Consider `cons concat`, this is how much information we *could* retain:\n", + "\n", + " (1 [.0.] [.1.] -- [1 .0. .1.])\n", + "\n", + "As opposed to just:\n", + "\n", + " (1 [.0.] [.1.] -- [.2.])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### represent `concat`\n", + "\n", + " ([.0.] [.1.] -- [A*(.0.) .1.])\n", + "\n", + "Meaning that `A*` on the right-hand side should all the crap from `.0.`.\n", + "\n", + " ([ .0.] [.1.] -- [ A* .1.])\n", + " ([a .0.] [.1.] -- [a A* .1.])\n", + " ([a b .0.] [.1.] -- [a b A* .1.])\n", + " ([a b c .0.] [.1.] -- [a b c A* .1.])\n", + "\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or...\n", + "\n", + " ([ .0.] [.1.] -- [ .1.])\n", + " ([a .0.] [.1.] -- [a .1.])\n", + " ([a b .0.] [.1.] -- [a b .1.])\n", + " ([a b c .0.] [.1.] -- [a b c .1.])\n", + " ([a A* c .0.] [.1.] -- [a A* c .1.])\n", + "\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " (a, (b, S0)) . S1 = (a, (b, (A*, S1)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class Astar(object):\n", + " def __repr__(self):\n", + " return 'A*'\n", + "\n", + "\n", + "def concat(s0, s1):\n", + " a = []\n", + " while isinstance(s0, tuple):\n", + " term, s0 = s0\n", + " a.append(term)\n", + " assert isinstance(s0, StackJoyType), repr(s0)\n", + " s1 = Astar(), s1\n", + " for term in reversed(a):\n", + " s1 = term, s1\n", + " return s1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "a, b = (A[1], S[0]), (A[2], S[1])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "concat(a, b)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, diff --git a/docs/Types.md b/docs/Types.md index b3f9f2a..395fcda 100644 --- a/docs/Types.md +++ b/docs/Types.md @@ -1,7 +1,15 @@ # Type Inference -Cf. ["Type Inference in Stack-Based Programming Languages"](http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/) by Rob Kleffner, 2017-03-10. +This notebook presents a simple type inferencer for Joy code. It can infer the stack effect of most Joy expressions. It built largely by means of existing ideas and research (some of it may be original but I'm not able to say, as I don't fully understand the all of the source material in the depth required to make that call.) A great overview of the existing knowledge is a talk ["Type Inference in Stack-Based Programming Languages"](http://prl.ccs.neu.edu/blog/2017/03/10/type-inference-in-stack-based-programming-languages/) given by Rob Kleffner on or about 2017-03-10 as part of a course on the history of programming languages. + +The notebook starts with a simple inferencer based on the work of Jaanus Pöial which we then progressively elaborate to cover more Joy semantics. Along the way we write a simple "compiler" that emits Python code for what I like to call Yin functions. + +Yin functions are those that only rearrange values in stacks, as opposed to Yang functions that actually work on the values themselves. It's interesting to note that a Joy with *only* stacks (no other kinds of values) can be made and is Turing-complete, therefore all Yang functions are actually Yin functions, and all computation can be performed by manipulations of structures of containers, which is a restatement of the Laws of Form. (Also, this implies that every program can be put into a form such that it can be computed in a single step, although that step may be enormous or unending.) + +Although I haven't completed it yet, a Joy based on Laws of Form provides the foundation for a provably correct computing system "down to the metal". This is my original and still primary motivation for developing Joy. (I want a proven-correct Operating System for a swarm of trash-collecting recycler robots. To trust it I have to implementment it myself from first principles, and I'm not smart enough to truly grok the existing literature and software, so I had to go look for and find LoF and Joy. Now that I have the mental tools to build my robot OS I can get down to it. + +Anyhow, here's type inference... ## Part I: Pöial's Rules @@ -608,7 +616,7 @@ C(cons, uncons) -## Part III: Compiling Stack Functions +## Part III: Compiling Yin Functions Now consider the Python function we would like to derive: @@ -1361,7 +1369,7 @@ neato(roll_up, swap, roll_down) ```python -# e.g. [popop] dip +# e.g. [popop] dipd neato(popdd, roll_down, pop) ``` @@ -1421,6 +1429,8 @@ print compile_('sqr', C(dup, mul)) return (n1, stack) +(Eventually I should come back around to this becuase it's not tooo difficult to exend this code to be able to compile e.g. `n3 = mul(n1, n2)` for `mul` and insert it in the right place with the right variable names. It requires a little more support from the library functions, in that we need to know to call `mul()` the Python function for `mul` the Joy function, but since *most* of the math functions (at least) are already wrappers it should be straightforward.) + #### `compilable()` The functions that *can* be compiled are the ones that have only `AnyJoyType` and `StackJoyType` labels in their stack effect comments. We can write a function to check that: @@ -1895,7 +1905,7 @@ While in the second it spawns an `A`, which we will label `e`: w/ {d: e} [ A* b .0.] U [ .1.] w/ {.1.: A* b .0.} - [ A* b .0.] U [ .1.] + [ A* b .0.] U [ A* b .0.] Giving us two unifiers: @@ -2235,15 +2245,13 @@ for result in unify(a, b): ## Part VII: Typing Combinators -TBD +In order to compute the stack effect of combinators you kinda have to have the quoted programs they expect available. In the most general case, the `i` combinator, you can't say anything about it's stack effect other than it expects one quote: -This is an open subject. + i (... [.1.] -- ... .1.) -The obvious thing is that you now need two pairs of tuples to describe the combinators' effects, a stack effect comment and an expression effect comment: +Or - dip (a [F] --)--(-- F a) - -One thing that might help is... + i (... [A* .1.] -- ... A*) Consider the type of: @@ -2258,210 +2266,9 @@ Obviously it would be: (a1 [..1] -- ... then what? +Without any information about the contents of the quote we can't say much about the result. -```python -class SymbolJoyType(AnyJoyType): prefix = 'F' - -W = map(SymbolJoyType, _R) - -k = S[0], ((W[1], S[2]), S[0]) -Symbol('cons') -print doc_from_stack_effect(*k) - -``` - - (-- [F1 .2.]) - - - -```python -dip_a = ((W[1], S[2]), (A[1], S[0])) -``` - - -```python -d = relabel(S[0], dip_a) -print doc_from_stack_effect(*d) -``` - - (-- a1001 [F1001 .1002.]) - - - -```python -s = list(unify(d[1], k[1]))[0] -s -``` - - - - - {s0: (a1001, s1000), s1002: s2, F1001: F1} - - - - -```python -j = update(s, k) -``` - - -```python -print doc_from_stack_effect(*j) -``` - - (a1001 -- a1001 [F1 .2.]) - - - -```python -j -``` - - - - - ((a1001, s1000), ((F1, s2), (a1001, s1000))) - - - - -```python -cons -``` - - - - - ((s1, (a1, s23)), ((a1, s1), s23)) - - - - -```python -for f in MC([k], [dup]): - print doc_from_stack_effect(*f) -``` - - (-- [F0 .1.] [F0 .1.]) - - - -```python -l = S[0], ((cons, S[2]), (A[1], S[0])) -``` - - -```python -print doc_from_stack_effect(*l) -``` - - (-- a1 [[[[.1.] a1 .23.] [a1 .1.] .23.] .2.]) - - - -```python - -def dip_t(F): - (quote, (a1, sec)) = F[1] - G = F[0], sec - P = S[3], (a1, S[3]) - a = [P] - while isinstance(quote, tuple): - term, quote = quote - a.append(term) - a.append(G) - return a[::-1] - - - - -``` - - -```python -from joy.utils.stack import iter_stack -``` - - -```python -a, b, c = dip_t(l) -``` - - -```python -a -``` - - - - - (s0, s0) - - - - -```python -b -``` - - - - - ((s1, (a1, s23)), ((a1, s1), s23)) - - - - -```python -c -``` - - - - - (s3, (a1, s3)) - - - - -```python -MC([a], [b]) -``` - - - - - [((s0, (a0, s1)), ((a0, s0), s1))] - - - - -```python -kjs = MC(MC([a], [b]), [c]) -kjs -``` - - - - - [((s0, (a0, s1)), (a1, ((a0, s0), s1)))] - - - - -```python -print doc_from_stack_effect(*kjs[0]) -``` - - (a0 [.0.] -- [a0 .0.] a1) - - - (a0 [.0.] -- [a0 .0.] a1) - - a0 [.0.] a1 [cons] dip - ---------------------------- - [a0 .0.] a1 +I think there's a way forward. If we convert our list of terms we are composing into a stack structure we can use it as a *Joy expression*, then we can treat the *output half* of a function's stack effect comment as a Joy interpreter stack, and just execute combinators directly. We can hybridize the compostition function with an interpreter to evaluate combinators, compose non-combinator functions, and put type variables on the stack. For combinators like `branch` that can have more than one stack effect we have to "split universes" again and return both. (Note: bug! If one branch doesn't type check the currect code ignores it, so you can think things are okay but have a type error waiting in the faled branch, I think... D'oh! FIXME!!!) ```python @@ -2533,102 +2340,6 @@ And that brings us to current Work-In-Progress. I'm pretty hopeful that the mix The rest of this stuff is junk and/or unfinished material. -### `concat` - -How to deal with `concat`? - - concat ([.0.] [.1.] -- [.0. .1.]) - -We would like to represent this in Python somehow... - - -```python -concat = (S[0], S[1]), ((S[0], S[1]),) -``` - -But this is actually `cons` with the first argument restricted to be a stack: - - ([.0.] [.1.] -- [[.0.] .1.]) - -What we have implemented so far would actually only permit: - - ([.0.] [.1.] -- [.2.]) - - -```python -concat = (S[0], S[1]), (S[2],) -``` - - -Which works but can lose information. Consider `cons concat`, this is how much information we *could* retain: - - (1 [.0.] [.1.] -- [1 .0. .1.]) - -As opposed to just: - - (1 [.0.] [.1.] -- [.2.]) - -### represent `concat` - - ([.0.] [.1.] -- [A*(.0.) .1.]) - -Meaning that `A*` on the right-hand side should all the crap from `.0.`. - - ([ .0.] [.1.] -- [ A* .1.]) - ([a .0.] [.1.] -- [a A* .1.]) - ([a b .0.] [.1.] -- [a b A* .1.]) - ([a b c .0.] [.1.] -- [a b c A* .1.]) - - - -or... - - ([ .0.] [.1.] -- [ .1.]) - ([a .0.] [.1.] -- [a .1.]) - ([a b .0.] [.1.] -- [a b .1.]) - ([a b c .0.] [.1.] -- [a b c .1.]) - ([a A* c .0.] [.1.] -- [a A* c .1.]) - - - - (a, (b, S0)) . S1 = (a, (b, (A*, S1))) - - -```python -class Astar(object): - def __repr__(self): - return 'A*' - - -def concat(s0, s1): - a = [] - while isinstance(s0, tuple): - term, s0 = s0 - a.append(term) - assert isinstance(s0, StackJoyType), repr(s0) - s1 = Astar(), s1 - for term in reversed(a): - s1 = term, s1 - return s1 -``` - - -```python -a, b = (A[1], S[0]), (A[2], S[1]) -``` - - -```python -concat(a, b) -``` - - - - - (a1, (A*, (a2, s1))) - - - ## Appendix: Joy in the Logical Paradigm For this to work the type label classes have to be modified to let `T >= t` succeed, where e.g. `T` is `IntJoyType` and `t` is `int` @@ -2644,7 +2355,7 @@ print doc_from_stack_effect(*F) ValueError Traceback (most recent call last) - in () + in () 1 F = reduce(C, (pop, swap, roll_down, rest, rest, cons, cons)) 2 ----> 3 print doc_from_stack_effect(*F) @@ -2764,3 +2475,225 @@ s[0] I *think* this might be sorta what I'm doing above with the `kav()` function... In any event "mixed-mode" interpreters that include values and type variables and can track constraints, etc. will be, uh, super-useful. And Abstract Interpretation should be a rich source of ideas. + +## Junk + + +```python +class SymbolJoyType(AnyJoyType): prefix = 'F' + +W = map(SymbolJoyType, _R) + +k = S[0], ((W[1], S[2]), S[0]) +Symbol('cons') +print doc_from_stack_effect(*k) + +``` + + +```python +dip_a = ((W[1], S[2]), (A[1], S[0])) +``` + + +```python +d = relabel(S[0], dip_a) +print doc_from_stack_effect(*d) +``` + + +```python +s = list(unify(d[1], k[1]))[0] +s +``` + + +```python +j = update(s, k) +``` + + +```python +print doc_from_stack_effect(*j) +``` + + +```python +j +``` + + +```python +cons +``` + + +```python +for f in MC([k], [dup]): + print doc_from_stack_effect(*f) +``` + + +```python +l = S[0], ((cons, S[2]), (A[1], S[0])) +``` + + +```python +print doc_from_stack_effect(*l) +``` + + +```python + +def dip_t(F): + (quote, (a1, sec)) = F[1] + G = F[0], sec + P = S[3], (a1, S[3]) + a = [P] + while isinstance(quote, tuple): + term, quote = quote + a.append(term) + a.append(G) + return a[::-1] + + + + +``` + + +```python +from joy.utils.stack import iter_stack +``` + + +```python +a, b, c = dip_t(l) +``` + + +```python +a +``` + + +```python +b +``` + + +```python +c +``` + + +```python +MC([a], [b]) +``` + + +```python +kjs = MC(MC([a], [b]), [c]) +kjs +``` + + +```python +print doc_from_stack_effect(*kjs[0]) +``` + + (a0 [.0.] -- [a0 .0.] a1) + + a0 [.0.] a1 [cons] dip + ---------------------------- + [a0 .0.] a1 + +### `concat` + +How to deal with `concat`? + + concat ([.0.] [.1.] -- [.0. .1.]) + +We would like to represent this in Python somehow... + + +```python +concat = (S[0], S[1]), ((S[0], S[1]),) +``` + +But this is actually `cons` with the first argument restricted to be a stack: + + ([.0.] [.1.] -- [[.0.] .1.]) + +What we have implemented so far would actually only permit: + + ([.0.] [.1.] -- [.2.]) + + +```python +concat = (S[0], S[1]), (S[2],) +``` + + +Which works but can lose information. Consider `cons concat`, this is how much information we *could* retain: + + (1 [.0.] [.1.] -- [1 .0. .1.]) + +As opposed to just: + + (1 [.0.] [.1.] -- [.2.]) + +### represent `concat` + + ([.0.] [.1.] -- [A*(.0.) .1.]) + +Meaning that `A*` on the right-hand side should all the crap from `.0.`. + + ([ .0.] [.1.] -- [ A* .1.]) + ([a .0.] [.1.] -- [a A* .1.]) + ([a b .0.] [.1.] -- [a b A* .1.]) + ([a b c .0.] [.1.] -- [a b c A* .1.]) + + + +or... + + ([ .0.] [.1.] -- [ .1.]) + ([a .0.] [.1.] -- [a .1.]) + ([a b .0.] [.1.] -- [a b .1.]) + ([a b c .0.] [.1.] -- [a b c .1.]) + ([a A* c .0.] [.1.] -- [a A* c .1.]) + + + + (a, (b, S0)) . S1 = (a, (b, (A*, S1))) + + +```python +class Astar(object): + def __repr__(self): + return 'A*' + + +def concat(s0, s1): + a = [] + while isinstance(s0, tuple): + term, s0 = s0 + a.append(term) + assert isinstance(s0, StackJoyType), repr(s0) + s1 = Astar(), s1 + for term in reversed(a): + s1 = term, s1 + return s1 +``` + + +```python +a, b = (A[1], S[0]), (A[2], S[1]) +``` + + +```python +concat(a, b) +``` diff --git a/docs/Types.rst b/docs/Types.rst index 0385776..4a1a80d 100644 --- a/docs/Types.rst +++ b/docs/Types.rst @@ -2,9 +2,43 @@ Type Inference ============== -Cf. `"Type Inference in Stack-Based Programming +This notebook presents a simple type inferencer for Joy code. It can +infer the stack effect of most Joy expressions. It built largely by +means of existing ideas and research (some of it may be original but I'm +not able to say, as I don't fully understand the all of the source +material in the depth required to make that call.) A great overview of +the existing knowledge is a talk `"Type Inference in Stack-Based +Programming Languages" `__ -by Rob Kleffner, 2017-03-10. +given by Rob Kleffner on or about 2017-03-10 as part of a course on the +history of programming languages. + +The notebook starts with a simple inferencer based on the work of Jaanus +Pöial which we then progressively elaborate to cover more Joy semantics. +Along the way we write a simple "compiler" that emits Python code for +what I like to call Yin functions. + +Yin functions are those that only rearrange values in stacks, as opposed +to Yang functions that actually work on the values themselves. It's +interesting to note that a Joy with *only* stacks (no other kinds of +values) can be made and is Turing-complete, therefore all Yang functions +are actually Yin functions, and all computation can be performed by +manipulations of structures of containers, which is a restatement of the +Laws of Form. (Also, this implies that every program can be put into a +form such that it can be computed in a single step, although that step +may be enormous or unending.) + +Although I haven't completed it yet, a Joy based on Laws of Form +provides the foundation for a provably correct computing system "down to +the metal". This is my original and still primary motivation for +developing Joy. (I want a proven-correct Operating System for a swarm of +trash-collecting recycler robots. To trust it I have to implementment it +myself from first principles, and I'm not smart enough to truly grok the +existing literature and software, so I had to go look for and find LoF +and Joy. Now that I have the mental tools to build my robot OS I can get +down to it. + +Anyhow, here's type inference... Part I: Pöial's Rules --------------------- @@ -761,8 +795,8 @@ deal with this recursively: -Part III: Compiling Stack Functions ------------------------------------ +Part III: Compiling Yin Functions +--------------------------------- Now consider the Python function we would like to derive: @@ -1605,7 +1639,7 @@ also get the effect of combinators in some limited cases. .. code:: ipython2 - # e.g. [popop] dip + # e.g. [popop] dipd neato(popdd, roll_down, pop) @@ -1676,6 +1710,14 @@ such. Note that this is *not* a ``sqr`` function implementation: return (n1, stack) +(Eventually I should come back around to this becuase it's not tooo +difficult to exend this code to be able to compile e.g. +``n3 = mul(n1, n2)`` for ``mul`` and insert it in the right place with +the right variable names. It requires a little more support from the +library functions, in that we need to know to call ``mul()`` the Python +function for ``mul`` the Joy function, but since *most* of the math +functions (at least) are already wrappers it should be straightforward.) + ``compilable()`` ^^^^^^^^^^^^^^^^ @@ -2231,7 +2273,7 @@ While in the second it spawns an ``A``, which we will label ``e``: w/ {d: e} [ A* b .0.] U [ .1.] w/ {.1.: A* b .0.} - [ A* b .0.] U [ .1.] + [ A* b .0.] U [ A* b .0.] Giving us two unifiers: @@ -2601,19 +2643,20 @@ This function has to be modified to yield multiple results. Part VII: Typing Combinators ---------------------------- -TBD - -This is an open subject. - -The obvious thing is that you now need two pairs of tuples to describe -the combinators' effects, a stack effect comment and an expression -effect comment: +In order to compute the stack effect of combinators you kinda have to +have the quoted programs they expect available. In the most general +case, the ``i`` combinator, you can't say anything about it's stack +effect other than it expects one quote: :: - dip (a [F] --)--(-- F a) + i (... [.1.] -- ... .1.) -One thing that might help is... +Or + +:: + + i (... [A* .1.] -- ... A*) Consider the type of: @@ -2633,226 +2676,20 @@ Obviously it would be: (a1 [..1] -- ... then what? -.. code:: ipython2 - - class SymbolJoyType(AnyJoyType): prefix = 'F' - - W = map(SymbolJoyType, _R) - - k = S[0], ((W[1], S[2]), S[0]) - Symbol('cons') - print doc_from_stack_effect(*k) - - - -.. parsed-literal:: - - (-- [F1 .2.]) - - -.. code:: ipython2 - - dip_a = ((W[1], S[2]), (A[1], S[0])) - -.. code:: ipython2 - - d = relabel(S[0], dip_a) - print doc_from_stack_effect(*d) - - -.. parsed-literal:: - - (-- a1001 [F1001 .1002.]) - - -.. code:: ipython2 - - s = list(unify(d[1], k[1]))[0] - s - - - - -.. parsed-literal:: - - {s0: (a1001, s1000), s1002: s2, F1001: F1} - - - -.. code:: ipython2 - - j = update(s, k) - -.. code:: ipython2 - - print doc_from_stack_effect(*j) - - -.. parsed-literal:: - - (a1001 -- a1001 [F1 .2.]) - - -.. code:: ipython2 - - j - - - - -.. parsed-literal:: - - ((a1001, s1000), ((F1, s2), (a1001, s1000))) - - - -.. code:: ipython2 - - cons - - - - -.. parsed-literal:: - - ((s1, (a1, s23)), ((a1, s1), s23)) - - - -.. code:: ipython2 - - for f in MC([k], [dup]): - print doc_from_stack_effect(*f) - - -.. parsed-literal:: - - (-- [F0 .1.] [F0 .1.]) - - -.. code:: ipython2 - - l = S[0], ((cons, S[2]), (A[1], S[0])) - -.. code:: ipython2 - - print doc_from_stack_effect(*l) - - -.. parsed-literal:: - - (-- a1 [[[[.1.] a1 .23.] [a1 .1.] .23.] .2.]) - - -.. code:: ipython2 - - - def dip_t(F): - (quote, (a1, sec)) = F[1] - G = F[0], sec - P = S[3], (a1, S[3]) - a = [P] - while isinstance(quote, tuple): - term, quote = quote - a.append(term) - a.append(G) - return a[::-1] - - - - - -.. code:: ipython2 - - from joy.utils.stack import iter_stack - -.. code:: ipython2 - - a, b, c = dip_t(l) - -.. code:: ipython2 - - a - - - - -.. parsed-literal:: - - (s0, s0) - - - -.. code:: ipython2 - - b - - - - -.. parsed-literal:: - - ((s1, (a1, s23)), ((a1, s1), s23)) - - - -.. code:: ipython2 - - c - - - - -.. parsed-literal:: - - (s3, (a1, s3)) - - - -.. code:: ipython2 - - MC([a], [b]) - - - - -.. parsed-literal:: - - [((s0, (a0, s1)), ((a0, s0), s1))] - - - -.. code:: ipython2 - - kjs = MC(MC([a], [b]), [c]) - kjs - - - - -.. parsed-literal:: - - [((s0, (a0, s1)), (a1, ((a0, s0), s1)))] - - - -.. code:: ipython2 - - print doc_from_stack_effect(*kjs[0]) - - -.. parsed-literal:: - - (a0 [.0.] -- [a0 .0.] a1) - - -:: - - (a0 [.0.] -- [a0 .0.] a1) - - a0 [.0.] a1 [cons] dip - ---------------------------- - [a0 .0.] a1 +Without any information about the contents of the quote we can't say +much about the result. + +I think there's a way forward. If we convert our list of terms we are +composing into a stack structure we can use it as a *Joy expression*, +then we can treat the *output half* of a function's stack effect comment +as a Joy interpreter stack, and just execute combinators directly. We +can hybridize the compostition function with an interpreter to evaluate +combinators, compose non-combinator functions, and put type variables on +the stack. For combinators like ``branch`` that can have more than one +stack effect we have to "split universes" again and return both. (Note: +bug! If one branch doesn't type check the currect code ignores it, so +you can think things are okay but have a type error waiting in the faled +branch, I think... D'oh! FIXME!!!) .. code:: ipython2 @@ -2924,117 +2761,6 @@ the pace I should be able to verify that conjecture by the end of June. The rest of this stuff is junk and/or unfinished material. -``concat`` -~~~~~~~~~~ - -How to deal with ``concat``? - -:: - - concat ([.0.] [.1.] -- [.0. .1.]) - -We would like to represent this in Python somehow... - -.. code:: ipython2 - - concat = (S[0], S[1]), ((S[0], S[1]),) - -But this is actually ``cons`` with the first argument restricted to be a -stack: - -:: - - ([.0.] [.1.] -- [[.0.] .1.]) - -What we have implemented so far would actually only permit: - -:: - - ([.0.] [.1.] -- [.2.]) - -.. code:: ipython2 - - concat = (S[0], S[1]), (S[2],) - -Which works but can lose information. Consider ``cons concat``, this is -how much information we *could* retain: - -:: - - (1 [.0.] [.1.] -- [1 .0. .1.]) - -As opposed to just: - -:: - - (1 [.0.] [.1.] -- [.2.]) - -represent ``concat`` -~~~~~~~~~~~~~~~~~~~~ - -:: - - ([.0.] [.1.] -- [A*(.0.) .1.]) - -Meaning that ``A*`` on the right-hand side should all the crap from -``.0.``. - -:: - - ([ .0.] [.1.] -- [ A* .1.]) - ([a .0.] [.1.] -- [a A* .1.]) - ([a b .0.] [.1.] -- [a b A* .1.]) - ([a b c .0.] [.1.] -- [a b c A* .1.]) - -or... - -:: - - ([ .0.] [.1.] -- [ .1.]) - ([a .0.] [.1.] -- [a .1.]) - ([a b .0.] [.1.] -- [a b .1.]) - ([a b c .0.] [.1.] -- [a b c .1.]) - ([a A* c .0.] [.1.] -- [a A* c .1.]) - -:: - - (a, (b, S0)) . S1 = (a, (b, (A*, S1))) - -.. code:: ipython2 - - class Astar(object): - def __repr__(self): - return 'A*' - - - def concat(s0, s1): - a = [] - while isinstance(s0, tuple): - term, s0 = s0 - a.append(term) - assert isinstance(s0, StackJoyType), repr(s0) - s1 = Astar(), s1 - for term in reversed(a): - s1 = term, s1 - return s1 - -.. code:: ipython2 - - a, b = (A[1], S[0]), (A[2], S[1]) - -.. code:: ipython2 - - concat(a, b) - - - - -.. parsed-literal:: - - (a1, (A*, (a2, s1))) - - - Appendix: Joy in the Logical Paradigm ------------------------------------- @@ -3056,7 +2782,7 @@ For this to work the type label classes have to be modified to let ValueError Traceback (most recent call last) - in () + in () 1 F = reduce(C, (pop, swap, roll_down, rest, rest, cons, cons)) 2 ----> 3 print doc_from_stack_effect(*F) @@ -3174,3 +2900,221 @@ function... In any event "mixed-mode" interpreters that include values and type variables and can track constraints, etc. will be, uh, super-useful. And Abstract Interpretation should be a rich source of ideas. + +Junk +---- + +.. code:: ipython2 + + class SymbolJoyType(AnyJoyType): prefix = 'F' + + W = map(SymbolJoyType, _R) + + k = S[0], ((W[1], S[2]), S[0]) + Symbol('cons') + print doc_from_stack_effect(*k) + + +.. code:: ipython2 + + dip_a = ((W[1], S[2]), (A[1], S[0])) + +.. code:: ipython2 + + d = relabel(S[0], dip_a) + print doc_from_stack_effect(*d) + +.. code:: ipython2 + + s = list(unify(d[1], k[1]))[0] + s + +.. code:: ipython2 + + j = update(s, k) + +.. code:: ipython2 + + print doc_from_stack_effect(*j) + +.. code:: ipython2 + + j + +.. code:: ipython2 + + cons + +.. code:: ipython2 + + for f in MC([k], [dup]): + print doc_from_stack_effect(*f) + +.. code:: ipython2 + + l = S[0], ((cons, S[2]), (A[1], S[0])) + +.. code:: ipython2 + + print doc_from_stack_effect(*l) + +.. code:: ipython2 + + + def dip_t(F): + (quote, (a1, sec)) = F[1] + G = F[0], sec + P = S[3], (a1, S[3]) + a = [P] + while isinstance(quote, tuple): + term, quote = quote + a.append(term) + a.append(G) + return a[::-1] + + + + + +.. code:: ipython2 + + from joy.utils.stack import iter_stack + +.. code:: ipython2 + + a, b, c = dip_t(l) + +.. code:: ipython2 + + a + +.. code:: ipython2 + + b + +.. code:: ipython2 + + c + +.. code:: ipython2 + + MC([a], [b]) + +.. code:: ipython2 + + kjs = MC(MC([a], [b]), [c]) + kjs + +.. code:: ipython2 + + print doc_from_stack_effect(*kjs[0]) + +:: + + (a0 [.0.] -- [a0 .0.] a1) + + a0 [.0.] a1 [cons] dip + ---------------------------- + [a0 .0.] a1 + +``concat`` +~~~~~~~~~~ + +How to deal with ``concat``? + +:: + + concat ([.0.] [.1.] -- [.0. .1.]) + +We would like to represent this in Python somehow... + +.. code:: ipython2 + + concat = (S[0], S[1]), ((S[0], S[1]),) + +But this is actually ``cons`` with the first argument restricted to be a +stack: + +:: + + ([.0.] [.1.] -- [[.0.] .1.]) + +What we have implemented so far would actually only permit: + +:: + + ([.0.] [.1.] -- [.2.]) + +.. code:: ipython2 + + concat = (S[0], S[1]), (S[2],) + +Which works but can lose information. Consider ``cons concat``, this is +how much information we *could* retain: + +:: + + (1 [.0.] [.1.] -- [1 .0. .1.]) + +As opposed to just: + +:: + + (1 [.0.] [.1.] -- [.2.]) + +represent ``concat`` +~~~~~~~~~~~~~~~~~~~~ + +:: + + ([.0.] [.1.] -- [A*(.0.) .1.]) + +Meaning that ``A*`` on the right-hand side should all the crap from +``.0.``. + +:: + + ([ .0.] [.1.] -- [ A* .1.]) + ([a .0.] [.1.] -- [a A* .1.]) + ([a b .0.] [.1.] -- [a b A* .1.]) + ([a b c .0.] [.1.] -- [a b c A* .1.]) + +or... + +:: + + ([ .0.] [.1.] -- [ .1.]) + ([a .0.] [.1.] -- [a .1.]) + ([a b .0.] [.1.] -- [a b .1.]) + ([a b c .0.] [.1.] -- [a b c .1.]) + ([a A* c .0.] [.1.] -- [a A* c .1.]) + +:: + + (a, (b, S0)) . S1 = (a, (b, (A*, S1))) + +.. code:: ipython2 + + class Astar(object): + def __repr__(self): + return 'A*' + + + def concat(s0, s1): + a = [] + while isinstance(s0, tuple): + term, s0 = s0 + a.append(term) + assert isinstance(s0, StackJoyType), repr(s0) + s1 = Astar(), s1 + for term in reversed(a): + s1 = term, s1 + return s1 + +.. code:: ipython2 + + a, b = (A[1], S[0]), (A[2], S[1]) + +.. code:: ipython2 + + concat(a, b) diff --git a/docs/sphinx_docs/_build/html/notebooks/index.html b/docs/sphinx_docs/_build/html/notebooks/index.html index 4269353..6176ea2 100644 --- a/docs/sphinx_docs/_build/html/notebooks/index.html +++ b/docs/sphinx_docs/_build/html/notebooks/index.html @@ -121,13 +121,14 @@
  • Type Inference
  • No Updates
  • diff --git a/docs/sphinx_docs/_build/html/searchindex.js b/docs/sphinx_docs/_build/html/searchindex.js index d3e2225..b1b24e8 100644 --- a/docs/sphinx_docs/_build/html/searchindex.js +++ b/docs/sphinx_docs/_build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Recursion_Combinators","notebooks/Replacing","notebooks/Treestep","notebooks/Types","notebooks/Zipper","notebooks/index","parser","pretty","stack"],envversion:52,filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Recursion_Combinators.rst","notebooks/Replacing.rst","notebooks/Treestep.rst","notebooks/Types.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst"],objects:{"joy.joy":{joy:[1,1,1,""],repl:[1,1,1,""],run:[1,1,1,""]},"joy.library":{"void":[3,1,1,""],BinaryBuiltinWrapper:[3,1,1,""],DefinitionWrapper:[3,2,1,""],FunctionWrapper:[3,1,1,""],SimpleFunctionWrapper:[3,1,1,""],UnaryBuiltinWrapper:[3,1,1,""],add_aliases:[3,1,1,""],app1:[3,1,1,""],app2:[3,1,1,""],app3:[3,1,1,""],b:[3,1,1,""],branch:[3,1,1,""],choice:[3,1,1,""],clear:[3,1,1,""],cmp_:[3,1,1,""],concat_:[3,1,1,""],cond:[3,1,1,""],dip:[3,1,1,""],dipd:[3,1,1,""],dipdd:[3,1,1,""],divmod_:[3,1,1,""],drop:[3,1,1,""],dupdip:[3,1,1,""],floor:[3,1,1,""],genrec:[3,1,1,""],getitem:[3,1,1,""],help_:[3,1,1,""],i:[3,1,1,""],id_:[3,1,1,""],ifte:[3,1,1,""],infra:[3,1,1,""],initialize:[3,1,1,""],inscribe:[3,1,1,""],loop:[3,1,1,""],map_:[3,1,1,""],max_:[3,1,1,""],min_:[3,1,1,""],parse:[3,1,1,""],pm:[3,1,1,""],pred:[3,1,1,""],remove:[3,1,1,""],reverse:[3,1,1,""],select:[3,1,1,""],sharing:[3,1,1,""],shunt:[3,1,1,""],sort_:[3,1,1,""],sqrt:[3,1,1,""],step:[3,1,1,""],succ:[3,1,1,""],sum_:[3,1,1,""],swaack:[3,1,1,""],take:[3,1,1,""],times:[3,1,1,""],unique:[3,1,1,""],unstack:[3,1,1,""],warranty:[3,1,1,""],words:[3,1,1,""],x:[3,1,1,""],zip_:[3,1,1,""]},"joy.library.DefinitionWrapper":{add_def:[3,3,1,""],add_definitions:[3,3,1,""],parse_definition:[3,3,1,""]},"joy.parser":{ParseError:[18,4,1,""],Symbol:[18,2,1,""],text_to_expression:[18,1,1,""]},"joy.utils":{generated_library:[3,0,0,"-"],pretty_print:[19,0,0,"-"],stack:[20,0,0,"-"]},"joy.utils.generated_library":{ccons:[3,1,1,""],cons:[3,1,1,""],dup:[3,1,1,""],dupd:[3,1,1,""],dupdd:[3,1,1,""],first:[3,1,1,""],first_two:[3,1,1,""],fourth:[3,1,1,""],over:[3,1,1,""],pop:[3,1,1,""],popd:[3,1,1,""],popdd:[3,1,1,""],popop:[3,1,1,""],popopd:[3,1,1,""],popopdd:[3,1,1,""],rest:[3,1,1,""],rolldown:[3,1,1,""],rollup:[3,1,1,""],rrest:[3,1,1,""],second:[3,1,1,""],stack:[3,1,1,""],stuncons:[3,1,1,""],stununcons:[3,1,1,""],swap:[3,1,1,""],swons:[3,1,1,""],third:[3,1,1,""],tuck:[3,1,1,""],uncons:[3,1,1,""],unswons:[3,1,1,""]},"joy.utils.pretty_print":{TracePrinter:[19,2,1,""]},"joy.utils.pretty_print.TracePrinter":{go:[19,5,1,""],viewer:[19,5,1,""]},"joy.utils.stack":{concat:[20,1,1,""],expression_to_string:[20,1,1,""],iter_stack:[20,1,1,""],list_to_stack:[20,1,1,""],pick:[20,1,1,""],stack_to_string:[20,1,1,""]},joy:{joy:[1,0,0,"-"],library:[3,0,0,"-"],parser:[18,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","classmethod","Python class method"],"4":["py","exception","Python exception"],"5":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:classmethod","4":"py:exception","5":"py:method"},terms:{"0b11100111011011":5,"23rd":15,"4b4cb6ff86e5":15,"5bkei":10,"5eb7ac5ad2c2":15,"\u03b5":8,"abstract":[7,10,17],"boolean":[2,3,7,10],"break":[7,15],"byte":5,"case":[2,3,12,14,15,20],"class":[3,7,15,18,19,20],"default":[3,6,10,20],"export":[3,18],"final":[2,10,12],"float":[3,7,15,16,18],"function":[0,1,4,5,6,9,11,16,17,18,19,20],"g\u00e9rard":16,"import":[2,5,6,8,10,11,12,13,14,15,16],"int":[6,7,12,15,16,18,20],"long":[10,17],"new":[2,3,6,7,9,12,13,15],"p\u00f6ial":17,"p\u00f6ial06typingtool":15,"public":9,"return":[1,3,5,7,10,12,13,14,15,18,19,20],"static":[2,9],"super":15,"switch":[2,15],"throw":10,"true":[2,3,5,12,15],"try":[6,8,11,12,14,15],"void":[0,3],"while":[3,7,10,15,18,20],Adding:[7,13,17],And:[5,6,8,10,12,15,16,20],But:[0,4,5,6,7,10,13,15],CPS:7,For:[2,3,10,12,13,15,17,20],Has:3,Its:3,One:[2,7,15,17],TOS:[2,3],That:[5,10],The:[0,1,2,3,4,6,8,9,11,15,16,17,18,20],Then:[2,3,10,11,12,15],There:[11,12,14,15,20],These:[15,17,20],Use:[3,8,12],Using:[0,8,10,17],With:[8,12,15,17],_1000:15,__add__:15,__class__:15,__eq__:15,__ge__:15,__hash__:15,__init__:15,__main__:15,__radd__:15,__repr__:15,__str__:19,_names_for:15,_to_str:15,_tree_add_:10,_tree_add_e:10,_tree_add_p:10,_tree_add_r:10,_tree_add_t:10,_tree_delete_:10,_tree_delete_clear_stuff:10,_tree_delete_del:10,_tree_delete_r0:10,_tree_delete_r1:10,_tree_delete_rightmost:10,_tree_delete_w:10,_tree_get_:10,_tree_get_p:10,_tree_get_r:10,_tree_get_t:10,_tree_iter_order_curr:10,_tree_iter_order_left:10,_tree_iter_order_r:10,_tree_iter_order_right:10,_tree_t:10,_treestep_0:14,_treestep_1:14,_uniqu:15,_within_b:8,_within_p:8,_within_r:8,a10001:15,a10002:15,a10003:15,a10004:15,a1001:15,abbrevi:14,abil:15,abl:15,about:[0,7,10,16,20],abov:[0,5,8,10,12,15],abs:8,absolut:7,accept:[1,2,3,5,6,7,10,11,13,14,15,16],accordingli:10,accumul:5,action:[7,13,15,16],actual:[2,5,7,10,15],adapt:17,add:[3,5,6,7,13,15,19],add_alias:3,add_def:3,add_definit:[3,10,14],added:[4,10],adding:[9,15],addit:[0,2,3,5,7,12,13,14],address:17,adjust:10,after:[5,6,7,12],afterward:7,again:[2,3,5,7,10,12,15],aggreg:16,ahead:15,aka:[7,16],albrecht:0,algorithm:[7,15],alia:3,alias:[3,7],align:[7,19],all:[3,5,6,7,10,12,13,14,15,19],alloc:15,allow:[9,10],almost:10,along:[7,12,15],alphabet:3,alreadi:[8,13,15,16],also:[0,5,7,10,15,20],alter:15,altern:[4,15],although:[4,10],altogeth:6,alwai:[5,9,12],amaz:15,among:15,amort:10,analysi:[4,17],anamorph:[7,17],ani:[4,5,7,9,10,15,16,18],annual:7,anonym:10,anoth:[10,15,20],anyjoytyp:15,anymor:15,anystarjoytyp:15,anyth:[2,3,7,15],api:9,app1:3,app2:[3,7,11,12,13],app3:3,app:7,appear:[2,4,5,10],append:15,appendix:17,appli:[2,3,5,6,10,12,15],applic:6,approach:5,approxim:17,archiv:0,aren:16,arg:[2,3],argument:[2,3,7,8,11,12,17,19,20],arithmet:2,ariti:2,around:[5,20],arrang:14,arriv:[6,14],articl:[0,4,6,12],ask:[4,6,15],aspect:0,assert:15,assign:20,associ:10,assum:8,astar:15,asterisk:14,asterix:15,attack:7,attempt:[0,1],attribut:3,attributeerror:15,author:15,auto:0,automat:[4,15],auxiliari:14,avail:[0,15],averag:[7,13],avoid:10,awai:10,awar:2,awkward:[10,12],azur:17,back:10,backward:[9,10,11,14],bag:7,banana:12,barb:12,base:[0,2,3,9,12,14,15],basic:[1,2,3,7,10],becaus:[2,3,7,10,14,15,16,20],becom:[10,14,20],been:[8,9,10,15,16],befor:[6,7,10],begin:[10,14],behavior:[9,14],behaviour:[0,1,15],being:0,below:[2,3,5,6,10,15,16],bespok:7,best:0,better:[5,10,12],between:[0,5],beyond:6,biannual:7,binari:[0,6,7,17],binary_search_tre:10,binarybuiltinwrapp:3,bind:7,bingo:16,bit:[5,6,10,15],block:5,bodi:[2,7,10],body_text:3,booktitl:15,bool:12,borrow:[7,15],both:[2,5,7,11,12,13,15,20],bottom:6,bracket:[7,15,18],branch:[3,5,6,12],breakpoint:7,bring:[5,7,15],bruijn:15,brzozowski:15,btree:[10,14],buck:10,bug:[0,7],build:[6,7,11,12,16,20],built:[11,15],bundl:[2,3,12],burgeon:7,calculu:4,call:[2,7,9,10,12,15,19,20],caller:10,can:[0,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,20],cannot:15,captur:7,card:7,care:[5,20],carefulli:16,carri:[6,10],cartesian:4,catamorph:17,categor:[0,17],categori:4,ccc:4,ccon:[3,10,15],cell:[12,15],certain:[7,20],certainli:10,chain:3,chang:[2,9,10,15,16],charact:16,chat:7,chatter:[0,15],check:[6,8,15],child:14,choic:[3,12],choos:9,chop:11,cinf:10,circuit:4,cite_not:10,classmethod:3,claus:[3,15],clean:15,clear:[3,5,7],clear_stuff:10,cleav:[7,11,13],close:[0,1,4],clunki:[5,15],cmp:[3,14,17],cmp_:3,code:[0,1,4,11,12,15,17],codireco:[6,8],collaps:12,collect:[4,6,7,15],combin:[0,3,5,6,7,8,11,14,16,17],combinatorjoytyp:15,come:[7,10],command:[7,10,15],common:[2,5],compar:[3,4,15],comparison:[0,10],compel:4,compil:[2,4,7,10,13,17],complet:4,complex:[3,15,16],complic:15,composit:15,compound:10,comput:[2,4,5,7,11,15],con:[3,5,6,7,8,10,11,12,14,16,20],conal:4,concat:[3,6,7,14,20],concat_:3,concaten:0,concatin:[0,3,20],conclus:17,concurr:2,cond:[3,10],condit:[3,7],confer:15,conflict:[10,15],conjectur:15,consecut:17,consid:[5,6,10,12,14,15,16],consist:[2,6,7,14],constant:10,constitu:12,constraint:15,construct:15,consum:15,contain:[0,2,3,6,7,12],context:2,conting:10,continu:[0,12,15,16],control:7,conveni:[4,15],convers:15,convert:[12,13,14,15,18,20],cool:10,copi:[2,3,5,10,12,14,17],copyright:7,correspond:4,could:[2,4,5,7,9,10,15,16],count:[3,15],counter:[5,15],coupl:14,cours:[5,10],crack:10,crap:15,crash:10,creat:[0,2,3,5,8,10,15],creativ:15,crude:[10,15,18],current:[2,3,7,12,14,15,16,19],custom:9,cycl:[5,6],cython:7,dai:7,data:[2,3,12],datastructur:[0,2,12,15,17,18,20],datatyp:20,ddee30dbb1a6:15,ddididi:16,deal:[0,10],dealt:15,decid:10,declar:15,decor:3,decoupl:12,decrement:3,deduc:[5,15],deeper:0,deepli:4,def:[3,7,12,13,15,20],defaultdict:15,defi:3,defin:[2,3,4,5,6,7,8,9,11,12,13,15,16,17],definit:[2,3,5,6,7,9,10,12,14,15,17],definitionwrapp:[3,10,12,14],deleg:7,delet:17,deliber:15,demonstr:4,depend:[3,10,12],deposit:14,dequot:12,der:10,deriv:[2,3,5,7,8,10,15,17],describ:[3,4,10,12,14,15,18],descript:[5,7],descriptor:15,design:[2,3,10,17],desir:[7,14],destruct:10,detail:[7,10,15],detect:[6,10,12,15],determin:17,develop:[0,6,7,15,17],diagram:5,dialect:1,dict:[1,3,15],dictionari:[0,1,3,7,15,17],differ:[0,4,5,8,10,11,12,20],differenti:4,dig:[10,16],digit:5,dinfrirst:7,dip:[3,5,6,7,8,10,11,12,13,14,15,17],dip_a:15,dip_t:15,dipd:[3,6,7,10,11,12,16],dipdd:[3,10],direco:17,direct:7,directli:[5,14,15,20],disappear:[2,15],discard:[3,6,8,10,12],disciplin:10,disenstacken:7,disk:7,displac:2,displai:15,distiguish:15,ditch:10,div:[3,7],dive:14,divis:10,divmod:3,divmod_:[3,15],doc:[2,3,7,15],document:[17,18,20],doe:[0,1,4,6,7,13,17,19],doesn:[5,9,10,14,15,20],doing:[4,5,7,15,16],domain:[4,15],don:[5,7,10,15],done:[2,5,7,9,15],door:7,dot:19,doubl:[5,7,15],down:[2,8,12,16],down_to_zero:7,dozen:7,draft:[4,9],dream:7,drive:[6,8],driven:5,driver:6,drop:[3,10],dudipd:7,due:15,dup:[3,5,6,7,8,10,11,12,16,20],dupd:[3,15],dupdd:3,dupdip:[3,5,10,11,12],duplic:[3,10,12],durat:2,dure:[2,12],each:[2,3,4,5,7,12,13,14,15,19],easi:[0,10,14,15,16],easier:[3,10],easili:4,edit:17,effect:[2,3,7,16,17],effici:[6,13,16],either:[1,2,3,10,12,15],eleg:[7,10,15],element:2,elif:15,elimin:15,elliott:4,els:[2,3,12,15],embed:[4,10,16],emit:15,empti:[3,7,14,15,20],encapsul:7,enclos:7,encod:6,encount:15,end:[5,10,12,14,15,20],endless:6,enforc:[2,7],engend:7,enough:[7,12,19],enstacken:[6,7,15],enter:7,entir:20,entri:[3,16,19],enumer:15,epsilon:8,equal:[5,14,20],equat:[7,8],ergo:10,err:10,error:[7,18],essai:0,establish:15,etc:[3,14,15,16,18],euler:17,euro:15,eval:[0,15],evalu:[1,2,3,7,8,10,11,12,13,14],event:15,everi:6,everyth:[3,10,11,15],evolv:9,examin:12,exampl:[0,3,5,15,17,18,20],exce:6,except:[7,10,15,18],execut:[0,1,2,3,7,12,13,14,16,20],exercis:10,exist:[4,10],expand:10,expect:[2,3,14,20],experi:[7,14],explain:15,explan:7,explor:7,express:[0,1,2,3,4,10,12,13,15,16,19,20],expression_to_str:20,extend:15,extra:[5,6],extract:[10,11,17],extrem:7,extrememli:7,f1001:15,f_g:15,f_in:15,f_out:15,f_python:15,facet:0,facil:7,fact:18,factor:[2,5,7,10,15],factori:17,fail:[2,3,10,18],fairli:15,fals:[2,3,5,12,15],far:[8,10,12,15],fascin:0,fear:[10,15],few:[5,7,8,11],fewer:[3,7],fg_in:15,fg_out:15,fib:6,fib_gen:6,fibonacci:17,figur:[2,3,10,12],filter:10,fin:5,find:[2,3,5,6,14,15,17],finder:8,fine:[0,5,10,15],first:[3,6,7,8,10,11,12,13,14,16,17],first_two:[3,10],fit:[5,7],five:[5,7,17],fix:[2,3,12],flatten:[7,14],flexibl:17,floatjoytyp:15,floatstarjoytyp:15,floor:3,floordiv:5,flow:7,follow:[0,2,3,7,9,12,14,15,16],foo:[7,9,10,15],foo_ii:9,form:[2,3,4,5,6,12,14,15,20],forman:7,format:[15,17,19],formula:[0,5,17],forth:[7,15],forum:0,found:7,four:[2,3,5,6,7,10,17],fourteen:5,fourth:[2,3,10,12],fractal:7,fraction0:7,fraction:[2,7],frame:12,framework:7,free:[4,7,10],freeli:2,from:[0,1,2,3,5,6,7,8,10,11,12,13,14,15,16,17,20],front:[2,3,12],full:5,fun:17,func:15,functionwrapp:3,funtion:10,further:[8,15,17],g_in:15,g_out:15,garbag:7,gari:10,gcd:7,gener:[0,2,4,12,15,17,20],generated_librari:3,genrec:[3,7,10,12,14],geometr:5,get:[2,4,5,6,7,11,12,15,17],getitem:3,getrecursionlimit:20,getsourc:7,ghc:4,give:[4,5,10,12,14,15,20],given:[2,3,5,6,8,10,12,16,17],global:15,glue:7,going:[10,11,14,15,16],good:[5,10],grab:[3,15],grammar:18,grand:7,great:[0,7,17],greater:20,group:0,gsra:8,guard:10,had:[5,16],haiku:7,half:[5,16],hand:[7,13,15,17],handi:[8,15],handl:[10,15,20],happen:[7,15],hard:[15,16],hardwar:4,has:[0,2,6,7,8,9,10,12,15,16,20],hash:15,haskel:4,have:[2,3,5,6,7,8,9,12,13,15,16,17,20],head:20,help:[7,10,12,15],help_:3,helper:3,herd:7,here:[5,6,10,14,15,16],hide:10,hierarchi:15,higher:[7,10],highli:7,histori:[15,19],hmm:10,hoist:3,hold:[5,15],hood:10,hope:[0,5,7,15,17],hopefulli:12,host:17,how:[0,4,8,10,12,15,16,17],howev:[12,13,15],html:[2,3,6,11,12,17],http:10,huet:16,huge:10,hugh:[8,14],human:7,hylomorph:17,hypothet:2,id_:3,idea:[4,5,7,15],ident:[3,12],if_not_empti:10,ift:[3,10,12,14,15],ignor:[3,10,15],iii:17,illustr:12,imagin:16,imap:15,imit:14,immedi:12,immut:[7,10],imper:12,implement:[0,1,2,3,4,7,9,10,12,13,17],implicit:7,includ:[4,10,14,15],inclus:5,incom:20,incompat:9,incorpor:11,increas:5,increment:[3,4,5,9],index:[0,7,15,20],indexerror:20,indic:[14,15],ineffici:15,infer:[0,17],inform:[3,15],infra:[3,6,7,10,11,13,14,17],infrastructur:3,initi:[2,3,7,8,10],inlin:10,inner:15,inproceed:15,input:[1,8,15],inscrib:3,insight:12,inspect:7,instal:0,instanti:[4,19],instead:[5,6,10,12,15,16,20],integ:[2,3,7,12,14,15],integr:3,intend:[0,7],interact:[7,17],interest:[0,5,10,15,17],interlud:17,intermedi:12,intern:[0,15,19,20],interpret:[0,4,9,13,17,18,19],interrupt:7,interv:[4,5],intjoytyp:15,introduc:9,introduct:0,intstarjoytyp:15,intuit:15,invari:3,invent:15,involv:15,ipf:7,ipython:15,isinst:15,isn:[10,16],issubclass:15,item:[2,3,7,10,12,14,15,17,20],iter:[1,3,7,12,14,15,17,20],iter_stack:[13,15,20],iteritem:15,itertool:15,its:[0,2,3,4,5,7,10,12,14,15,20],itself:[0,2,7,10,15],j05cmp:[2,3,12],jaanu:15,job:17,john:[8,14],joi:[2,4,9,10,11,13],join:15,joypi:[7,16],june:15,junk:15,jupyt:17,just:[0,2,3,6,7,9,10,12,14,15,16],kav:15,keep:[10,11,15,16],kei:[14,17],kevin:0,key_n:10,keyerror:[10,15],kind:[2,4,7,10,12,14,15],kjs:15,kleen:[14,15],kleenestar:15,kleffner:15,know:[5,10],known:4,l_kei:10,l_left:10,l_right:10,l_valu:10,label:15,lambda:[4,15],languag:[4,7,9,10,13,15],larger:20,largest:3,last:[5,10,12,15],lastli:6,later:[7,14,15],law:2,lazi:15,lazili:8,lcm:5,lead:[7,15],leaf:10,lean:7,learn:0,least:[2,5,12,15,20],least_fract:7,leav:5,left:[7,11,12,14,15,16,19,20],leftov:12,len:15,length:[3,5,20],lens:12,less:[5,6,7,12,15,20],let:[6,8,10,11,12,14,15,16],letter:15,level:[4,10],librari:[0,13],like:[2,3,5,7,14,15,17,18],limit:15,line:[3,7,10,11,19],linear:20,link:0,linux:0,list:[0,3,5,7,8,10,12,14,16,19],list_to_stack:20,lit:15,liter:[1,10,14,15,16,18],literatur:15,littl:[6,10,15,17],live:17,lkei:14,load:[5,7],local:15,locat:2,locu:19,log_2:10,logic:[0,5,17],longer:[10,15],look:[6,7,8,10,11,15],lookup:7,loop:[0,1,3,5],lose:15,lot:[7,10,16],love:5,low:4,lower:5,lowercas:15,lowest:10,machin:0,machineri:[10,15],macro:7,made:[0,7,15,16],magic:15,mai:[2,12],mail:0,main:[0,3,7,11,15,16],mainloop:9,maintain:16,major:9,make:[2,3,4,5,7,10,12,13,14,15,16,17],make_gener:8,manfr:[0,2,3,4,12],mani:[0,7,15],manipul:15,manner:11,map:[1,3,5,7,9,12,14,15],map_:3,marker:7,mask:[5,6],match:[0,1],materi:[0,15],math:[0,7,8,10,11,15],mathemat:7,matter:[5,8,10,14],max_:3,maximum:3,mayb:10,mean:[4,5,7,8,10,12,14,15,20],meant:[7,10,12,14],member:[2,3,12],mental:7,mention:2,mercuri:0,mess:15,meta:[7,10,13],meta_compos:15,method:[0,3,7,15,17,19],midpoint:5,might:[4,6,10,15],mike:10,million:6,min_:3,mind:15,minimum:3,minor:10,minu:3,mirror:0,miscellan:0,mix:[7,15],mod:3,mode:15,model:[4,7,15],modern:0,modif:6,modifi:[7,10,16],modul:[0,1,3,7,15,18],modulu:7,moment:15,month:7,more:[0,3,4,5,6,7,8,12,13,14,15,18,20],most:15,mostli:0,move:10,movement:2,much:[5,6,10,12,15],muck:10,mul:[7,11,16,19],multi:3,multipl:17,must:[2,3,5,9,12,14,15],myself:15,n10001:15,n10002:15,n10003:15,n1001:15,n1002:15,n1003:15,name:[1,3,7,9,10,12,15,16,17,18,20],natur:[5,6,10],navig:16,nearli:15,neat:10,neato:15,necessarili:15,need:[2,3,5,6,8,9,10,12,15],neg:[3,11],nest:[3,7,10,16],network:7,never:[9,12],new_def:15,new_f:15,new_kei:10,new_valu:10,newton:[0,17],next:[5,14,15],nice:[0,12,20],niether:2,node:[14,17],node_kei:10,node_valu:10,non:14,none:[1,3,15],nope:14,notat:[7,10],note:[2,5,8,10,12,15,20],notebook:[5,6,7,15,16,17],notebook_preambl:[2,5,6,8,10,11,12,13,14,15,16],noth:[2,10],notic:5,now:[5,6,7,12,13,14,15,17],nth:[3,20],nullari:[7,10],number:[1,2,3,5,6,8,20],numberjoytyp:15,numberstarjoytyp:15,numer:15,object:[15,18],observ:5,obviou:[6,15],obvious:15,occur:10,odd:[5,6],off:[2,3,5,6,11,16],old:[2,13],old_k:10,old_kei:10,old_valu:10,omit:[12,15],onc:[3,9,10],one:[2,3,5,6,10,12,14,15,19,20],ones:[6,15],onli:[2,3,5,10,12,15,16,20],onto:[1,2,3,7,12,20],open:[7,15],oper:[3,7,10,12,20],oppos:15,optim:10,option:[1,7,10,20],order:[0,2,3,7,12,15,17,20],org:[0,10],origin:[0,1,2,3,10,16],other:[0,2,3,4,7,10,12,14,15,20],otherwis:[3,5,6,10,14,15],our:[5,6,7,8,12,14,15],out:[2,3,4,5,6,7,8,10,11,12,15,16],outcom:14,output:[8,12,15],outsid:4,over:[3,4,5,6,7,8,10,11,14,15,17],overhaul:15,own:[10,15],pace:15,pack:20,packag:[0,7],page:[0,10,15,20],pair:[2,3,5,6,10,15],palidrom:5,palindrom:5,pam:7,paper:[4,7,12,16],paradigm:17,parallel:2,paramet:[1,2,3,12,13,18,19,20],parameter:17,paramorph:12,parenthes:[10,20],pariti:6,pars:[0,3,7],parse_definit:3,parseerror:18,parser:[0,15],part:[2,3,8,12,14,17],partial:15,particular:16,pass:[0,10,15,19],path:17,pattern:[5,14,17],pe1:[5,6],pe2:6,pearl:16,pend:[3,7,12,16,19],peopl:17,per:[7,14],perform:15,perhap:6,period:7,permit:[15,20],permut:15,persist:10,phase:2,pick:[5,6,20],pickl:7,pictur:10,piec:12,pip:0,place:[3,5,7],plai:0,plu:3,plug:[6,12,14],point:[4,7,10,12],pointless:2,pop:[3,5,6,7,10,12,13,14,20],popd:[3,7,8,10,13,15],popdd:[3,6,11,15],popop:[3,5,6,7,8,10,14,15],popopd:3,popopdd:3,posit:[3,5,7,12],possibilit:10,possibl:[10,14,15,17],post:7,poswrd:15,power:7,pragmat:5,preambl:8,precis:[0,1],pred:[3,15],predic:[2,3,6,12],prefix:[15,19],preserv:[4,14],pretti:[8,10,11,14,15,19,20],pretty_print:0,previou:7,prime:8,primit:[2,3,15,17],primrec:[3,6,7,8,12],print:[0,1,2,3,15,19,20],probabl:[6,7,10,15],problem:[7,15,17],proc_curr:10,proc_left:10,proc_right:10,proce:5,process:[7,14,15,19],produc:[5,10,12,14,15],product:[6,7,15],program:[0,2,3,6,7,8,10,12,15,16],programm:15,progress:15,project:17,prompt:7,proper:[2,3,12],properti:0,provid:[0,3,4,7],pun:[0,7],punctuat:15,pure:0,puriti:7,purpos:7,push:[2,3,7,12,16,20],pushback:7,put:[1,2,6,7,15,17,20],pypi:0,python:[0,2,3,10,12,16,17,18,20],quadrat:[0,17],queri:[10,14],query_kei:14,queu:12,quit:[0,1,14],quot:[0,3,6,7,10,11,12,14,15,16,19],quotat:[2,3,12],quotient:3,r_kei:10,r_left:10,r_right:10,r_valu:10,rais:[10,15,18,20],rang:[7,15],range_revers:12,range_to_zero:7,ranger:12,ranger_revers:12,raphson:8,rather:[5,7,12,14],ratio:7,reach:[5,6,12],read:[0,1,5,6,10,15,16],readabl:13,reader:10,readi:15,real:10,realiz:[4,10],rearrang:[2,10,15],reason:[5,7,15],rebuild:[14,16],rec1:[2,3,12],rec2:[2,3,12],recent:15,recogn:18,record:[7,19],recur:[12,15],recurs:[0,2,3,6,7,8,15,17,20],recus:7,redefin:17,redistribut:[3,7],reduc:[2,15],redund:20,refactor:[7,9],refer:[0,2],regist:2,regular:[15,18],reimplement:17,relat:15,releas:9,remain:[2,7,9],remaind:[3,8],remind:15,remov:[3,10,15,20],render:17,repeat:5,repeatedli:5,repl:[0,1],replac:[0,2,3,6,11,12,14,15,16,17,20],repositori:0,repr:15,repres:[2,7,10,18,19],represent:20,reprod:6,repurpos:15,requir:20,res:15,resembl:7,respect:5,rest:[3,5,6,7,10,12,16,17,20],rest_two:10,restor:2,restrict:15,result:[1,2,3,5,10,11,12,14,15,16],resum:7,retain:15,retir:2,retri:7,reus:[10,15],revers:[3,5,6,12,15,16,20],revisit:15,rewrit:[3,7,15],rewritten:7,rich:15,rid:10,right:[6,7,11,14,15,17,19,20],rightest:10,rightmost:5,rkei:14,rob:15,roll:[3,8,10,14],roll_dn:15,roll_down:15,roll_up:15,rolldown:3,rollup:3,root:[3,8,11],round:15,rrest:[3,15],rule:17,run:[0,1,3,5,7,8,10,11,12,14,16],runtimeerror:20,s1000:15,s1002:15,s23:15,sai:[6,10,11,14,15],same:[2,4,5,10,15,20],sandwich:[2,3,12],save:[2,5,7],scan:3,scanner:[7,18],scenario:16,scope:[6,10],search:[0,10],sec:15,second:[3,7,10,12,14,20],section:12,see:[0,6,7,8,9,11,12,13,15,16,19],seem:[0,5,7,14,15],seen:[15,16],select:3,self:15,semant:[2,3,7,9,10,15],semi:7,send:7,sens:[0,2,5,15,16],separ:[7,15],seq:15,sequenc:[0,1,2,3,5,7,10,12,13,16,17,18],sequence_to_stack:15,seri:[5,6,10,16],ses:15,set:[2,3,12,15,17],seven:[5,6],sever:[0,4,7,12],share:[3,7],shelf:2,shift:[5,6],shorter:17,shorthand:10,should:[2,3,5,10,12,15],shouldn:7,show:[4,16],shunt:[3,16],side:[10,15],signifi:[7,10],similar:[10,14,15],simon:7,simpl:[7,12,15,20],simplefunctionwrapp:[3,13,15],simpler:14,simplest:[15,17],simpli:4,simplifi:[5,10,16],sinc:[2,5,10],singl:[3,6,7,13,15,18],situ:10,situat:10,six:[5,6,7],sixti:[5,6],size:[7,17],skeptic:7,skip:15,slight:8,slightli:[10,12,15],smallest:3,smart:10,softwar:7,solei:2,solut:[5,6],solvabl:7,some:[2,3,6,7,10,12,14,15,17,20],somehow:[10,15],someth:[2,9,10,15],sometim:10,somewher:[10,17],sort:[3,10,15],sort_:3,sorta:15,sourc:[0,1,3,15,17,18,19,20],space:[5,19],span:5,spawn:15,special:[6,10,15,17],specif:[0,4],specifi:[10,15],speed:13,spell:14,sphinx:[17,20],spirit:[0,1,14],split:15,sqr:[7,8,11,16],sqrt:[3,8,15],squar:[3,8,15,18],stack:[0,1,3,5,6,8,10,11,12,13,14,16,17,18,19],stack_concat:15,stack_effect:15,stack_effect_com:15,stack_to_str:20,stacki:15,stackjoytyp:15,stackstarjoytyp:15,stage:14,stai:[0,1],stand:4,standard:[7,10],star:[14,15],stare:10,start:[5,6,7,8,10,12,14],state:7,statement:3,step:[3,5,7,10,13,15,16,17],still:[10,15],stop:10,storag:[5,10],store:[5,12],stori:12,str:[1,15,18,19,20],straightforward:[1,6,8,17],stream:5,stretch:10,string:[1,2,3,7,15,16,18,19,20],structur:[7,14,15,16,17,20],stuff:[10,15],stuncon:3,stununcon:3,style:[0,4,15],sub:9,subclass:7,subject:[15,16],subset:15,substitut:[10,15],subtract:5,subtyp:17,succ:[3,15],succe:15,success:8,suffic:15,suffici:10,suffix:15,suggest:[4,10],suitabl:[3,4,5],sum:[3,6,7,11,12,13,14],sum_:[3,15],summand:5,sumtre:14,suppli:[10,18],support:[7,19,20],suspect:2,swaack:[3,11,13,16],swap:[3,5,6,7,8,10,12,13,14,16],swon:[3,6,7,12,14,15,16],swoncat:[6,7,8,12,14],swuncon:12,symbol:[2,3,15,16,17,18],symboljoytyp:15,symmetr:[5,10],syntact:7,syntax:[7,20],sys:20,system:[7,10],tabl:15,tag:15,tail:[10,15,17,20],take:[3,5,7,8,10,12,15,20],talk:[7,10,20],target:16,tast:4,tbd:[7,15],tear:12,technic:2,techniqu:[4,16],technolog:2,temporari:16,ten:5,term:[1,2,7,8,12,15,17,18,20],termin:[2,3,12],ternari:7,test:[2,3,12],text:[0,1,3,15],text_to_express:[7,15,18],textual:7,than:[0,3,5,6,7,8,12,14,15,20],thei:[2,5,6,7,10,12,15,16,18,20],them:[2,3,5,6,10,12,15,16,17],themselv:15,theori:[2,3,12],therefor:6,thi:[0,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20],thing:[2,6,10,12,15,16,18,20],think:[2,5,7,10,12,14,15],third:[3,6,7,10],thirti:5,those:[2,3,10,12,15,17],though:5,thought:7,thousand:5,thread:2,three:[2,3,5,7,10,11,14,15,17],through:[1,5,7,14,15,16,20],thun:[2,3,4,9,12],thunder:7,time:[3,5,7,8,10,12,15,16],titl:15,to_set:10,todai:7,todo:[7,18],togeth:[6,7,15,17],token:18,toler:17,too:[12,15],tool:[7,15],top:[2,3,7,12,15,19,20],total:5,tower:15,trace:[0,7,11,12,16,17,20],traceback:15,traceprint:19,track:[11,15,16],tracker:0,transform:4,translat:[4,11,15],travers:[0,17],treasur:0,treat:[0,2,3,12,17],treatment:6,tree:[0,7,17],treegrind:17,treestep:[0,17],tri:5,triangular_numb:12,trick:[5,15],tricki:15,trobe:0,trove:0,truthi:[3,7],tuck:[3,7,15],tupl:[3,7,15,20],turn:[2,3,15],twice:[10,12],two:[2,3,5,7,8,10,11,12,14,15,16,17,20],type:[0,1,4,7,10,12,17,18,19,20],typeerror:15,typeless:15,typic:[2,3,11,12],unari:7,unarybuiltinwrapp:3,unbalanc:[10,18],unchang:10,uncompil:15,uncon:[3,6,7,10,12,14,16],under:[2,3,7,10],underli:15,underscor:15,understand:[0,10],undistinguish:10,undocu:7,unfinish:15,unfortun:20,unif:15,uniqu:[3,10,15],unit:[7,12],univers:[0,7,15],unnecessari:17,unnecesssari:15,unpack:[2,3,10,15,20],unpair:5,unquot:[7,14],unstack:[3,15],unswon:3,untangl:12,until:6,unus:5,unusu:10,updat:[0,17],usag:7,use:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,20],used:[3,4,7,10,12,16,18,20],useful:[0,15],user:14,uses:[2,5,12],using:[3,6,10,11,12,14,16],usual:[0,2,12],util:[0,3,13,15],valid:15,valu:[0,2,3,5,7,8,11,12,13,14,15,17,20],value_n:10,valueerror:[15,20],variabl:[15,17],variant:10,variat:[12,17],varieti:[4,7],variou:0,vener:20,verbos:4,veri:[0,1,4,7,10,20],verifi:15,versa:[2,15],version:[0,1,2,6,9,14,16,17],via:7,vice:[2,15],view:[10,17],viewer:[1,7,9,19],vii:17,von:[0,2,3,4,12],wai:[0,2,3,4,5,7,12,13,15],want:[2,5,6,8,10,12,15],warranti:[3,7],wash:7,wast:7,web:20,websit:[0,5],welcom:7,well:[0,4,7,8,10,15,18],were:[7,15,16],what:[2,3,4,7,10,12,14,15,19],whatev:[2,3,12,14,20],when:[5,6,7,10,12,15,16,18,20],where:[2,3,7,10,12,15,17,20],whether:12,which:[0,1,3,5,7,8,10,12,14,15,16,20],whole:[2,3,5,12,14,15],whose:6,why:[8,14],wiki:10,wikipedia:[0,10,16],wildli:7,wind:7,wire:12,within:[7,10,13,17],without:[2,7,10,11,15],won:[10,15,20],word:[0,3,5,7,12,16],work:[0,3,5,6,7,8,10,11,12,14,15,16,20],worth:5,would:[2,5,6,7,8,10,12,15,16,20],wrap:[3,7],wrapper:15,write:[4,8,10,12,14,15,16,17,20],written:[0,1,8,10,13,15,20],wrong:2,wrote:15,xrang:15,year:[7,15],yet:[10,15,16],yield:[2,3,12,15,20],you:[0,2,3,5,6,7,9,10,11,12,13,14,15,16,19,20],your:[2,3,7,12,15],yourself:[7,10],zero:[3,10,12,14,15,18,20],zip:[5,15],zip_:3,zipper:[0,17],zstr:16},titles:["Thun 0.2.0 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","Developing a Program in Joy","Using x to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Recursive Combinators","Replacing Functions in the Dictionary","Treating Trees II: treestep","Type Inference","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026"],titleterms:{"abstract":15,"case":[8,10],"function":[2,3,7,8,10,12,13,14,15],"long":13,"new":10,"p\u00f6ial":15,"void":2,"while":2,Adding:10,One:[6,10],The:[5,7,10,12,14],There:7,Using:6,With:14,about:17,add:[2,10],adding:10,address:16,altern:14,ana:12,analysi:5,anamorph:[2,12],app1:2,app2:2,app3:2,appendix:[10,12,15],approxim:8,argument:15,auto:3,averag:2,base:[8,10],binari:[2,10,14],both:10,branch:[2,10],can:10,cata:12,catamorph:12,categor:4,chatter:2,child:10,choic:2,clear:2,cleav:2,cmp:10,code:[7,10],combin:[2,10,12,15],comment:15,compar:10,comparison:2,compil:[6,15],compile_:15,compos:15,comput:8,con:[2,15],concat:[2,15],conclus:12,consecut:8,continu:7,current:10,datastructur:[7,10,16],deal:15,defin:[10,14],definit:11,delabel:15,delet:10,deriv:[11,12,14],design:12,determin:16,develop:5,dialect:0,dictionari:13,dip:[2,16],dipd:2,dipdd:2,direco:6,disenstacken:2,distinguish:15,div:2,doc_from_stack_effect:15,document:0,doe:10,down_to_zero:2,drop:2,dup:[2,15],dupd:2,dupdip:2,effect:15,els:10,empti:10,enstacken:2,equal:10,essai:17,euler:[5,6],eval:7,even:6,exampl:[2,7,10,12,14],execut:19,express:[7,18],extract:14,factori:12,fibonacci:6,filter:5,find:[8,10,12],first:[2,5,15],five:6,flatten:2,flexibl:14,floordiv:2,formula:11,found:10,four:12,fun:12,further:5,gcd:2,gener:[3,5,6,8],genrec:2,get:[10,14],getitem:2,given:14,greater:10,group:2,have:[10,14],help:2,highest:10,host:0,how:[5,6],hylo:12,hylomorph:12,identifi:15,ift:2,iii:15,implement:15,indic:0,infer:15,inferenc:15,inform:0,infra:[2,16],integ:5,interest:6,interlud:10,intern:18,interpret:[1,7,15],item:16,iter:[5,10],joi:[0,1,3,5,7,12,15,16,17,18,19,20],just:5,kei:10,languag:0,least_fract:2,left:10,less:10,let:5,librari:[3,7,15],like:10,list:[2,15,20],literari:7,littl:5,logic:[2,15],loop:[2,7],lower:10,lshift:2,make:[6,8],mani:5,map:2,math:2,method:8,min:2,miscellan:2,mod:2,modifi:15,modulu:2,more:10,most:10,mul:[2,15],multipl:[5,6,15],must:10,name:11,neg:2,newton:8,next:8,node:10,non:10,now:10,nullari:2,number:[12,15],one:7,onli:7,order:[10,14],osdn:0,our:10,over:2,pack:5,pam:2,para:12,paradigm:15,parameter:[10,14],pars:[2,18],parser:[7,18],part:15,pass:7,path:16,pattern:12,per:10,pop:[2,15],popd:2,popop:2,pow:2,power:6,pred:2,predic:[5,8,10,14],pretty_print:19,primit:12,primrec:2,print:7,problem:[5,6],process:10,product:2,program:[4,5,11,14,17],project:[0,5,6],pure:7,put:[10,11,14],python:[7,13,15],quadrat:11,quick:0,quot:[2,20],rang:[2,5,12],range_to_zero:2,read:7,recur:[8,10],recurs:[10,12,14],redefin:[10,14],refactor:[5,10],refer:3,regular:7,reimplement:14,relabel:15,rem:2,remaind:2,remov:2,render:5,repl:7,replac:[10,13],repres:15,reset:6,rest:[2,15],revers:2,right:[10,16],rightmost:10,roll:[2,15],rolldown:2,rollup:2,rshift:2,rule:15,run:[2,6],second:[2,15],select:2,sequenc:[6,15,20],set:[8,10],shorter:13,should:7,shunt:2,simplest:5,size:[2,13],someth:[],sourc:10,special:12,sqr:[2,15],sqrt:[2,11],stack:[2,7,15,20],start:0,step:[2,12,14],straightforward:11,structur:10,style:7,sub:[2,10],subtyp:15,succ:2,sum:[2,5],swaack:2,swap:[2,15],swon:2,swoncat:2,symbol:[7,12],tabl:0,tail:12,take:2,term:[5,6,14],ternari:2,text:18,than:10,them:11,thi:10,third:[2,15],three:6,thun:[0,7],time:[2,6],togeth:[10,11,14],token:7,toler:8,trace:[13,19],traceprint:7,travers:[10,14,16],treat:[10,14],tree:[10,14,16],treegrind:14,treestep:14,triangular:12,truediv:2,truthi:2,tuck:2,two:6,type:15,unari:2,unbound:15,uncon:[2,15],unifi:15,unit:2,unnecessari:5,unquot:2,unstack:2,updat:[9,15],use:15,util:[19,20],valu:[6,10],variabl:11,variat:6,version:[5,10,13,15],view:7,vii:15,within:8,word:2,write:11,xor:2,zero:6,zip:2,zipper:16}}) \ No newline at end of file +Search.setIndex({docnames:["index","joy","lib","library","notebooks/Categorical","notebooks/Developing","notebooks/Generator_Programs","notebooks/Intro","notebooks/Newton-Raphson","notebooks/NoUpdates","notebooks/Ordered_Binary_Trees","notebooks/Quadratic","notebooks/Recursion_Combinators","notebooks/Replacing","notebooks/Treestep","notebooks/Types","notebooks/Zipper","notebooks/index","parser","pretty","stack"],envversion:52,filenames:["index.rst","joy.rst","lib.rst","library.rst","notebooks/Categorical.rst","notebooks/Developing.rst","notebooks/Generator_Programs.rst","notebooks/Intro.rst","notebooks/Newton-Raphson.rst","notebooks/NoUpdates.rst","notebooks/Ordered_Binary_Trees.rst","notebooks/Quadratic.rst","notebooks/Recursion_Combinators.rst","notebooks/Replacing.rst","notebooks/Treestep.rst","notebooks/Types.rst","notebooks/Zipper.rst","notebooks/index.rst","parser.rst","pretty.rst","stack.rst"],objects:{"joy.joy":{joy:[1,1,1,""],repl:[1,1,1,""],run:[1,1,1,""]},"joy.library":{"void":[3,1,1,""],BinaryBuiltinWrapper:[3,1,1,""],DefinitionWrapper:[3,2,1,""],FunctionWrapper:[3,1,1,""],SimpleFunctionWrapper:[3,1,1,""],UnaryBuiltinWrapper:[3,1,1,""],add_aliases:[3,1,1,""],app1:[3,1,1,""],app2:[3,1,1,""],app3:[3,1,1,""],b:[3,1,1,""],branch:[3,1,1,""],choice:[3,1,1,""],clear:[3,1,1,""],cmp_:[3,1,1,""],concat_:[3,1,1,""],cond:[3,1,1,""],dip:[3,1,1,""],dipd:[3,1,1,""],dipdd:[3,1,1,""],divmod_:[3,1,1,""],drop:[3,1,1,""],dupdip:[3,1,1,""],floor:[3,1,1,""],genrec:[3,1,1,""],getitem:[3,1,1,""],help_:[3,1,1,""],i:[3,1,1,""],id_:[3,1,1,""],ifte:[3,1,1,""],infra:[3,1,1,""],initialize:[3,1,1,""],inscribe:[3,1,1,""],loop:[3,1,1,""],map_:[3,1,1,""],max_:[3,1,1,""],min_:[3,1,1,""],parse:[3,1,1,""],pm:[3,1,1,""],pred:[3,1,1,""],remove:[3,1,1,""],reverse:[3,1,1,""],select:[3,1,1,""],sharing:[3,1,1,""],shunt:[3,1,1,""],sort_:[3,1,1,""],sqrt:[3,1,1,""],step:[3,1,1,""],succ:[3,1,1,""],sum_:[3,1,1,""],swaack:[3,1,1,""],take:[3,1,1,""],times:[3,1,1,""],unique:[3,1,1,""],unstack:[3,1,1,""],warranty:[3,1,1,""],words:[3,1,1,""],x:[3,1,1,""],zip_:[3,1,1,""]},"joy.library.DefinitionWrapper":{add_def:[3,3,1,""],add_definitions:[3,3,1,""],parse_definition:[3,3,1,""]},"joy.parser":{ParseError:[18,4,1,""],Symbol:[18,2,1,""],text_to_expression:[18,1,1,""]},"joy.utils":{generated_library:[3,0,0,"-"],pretty_print:[19,0,0,"-"],stack:[20,0,0,"-"]},"joy.utils.generated_library":{ccons:[3,1,1,""],cons:[3,1,1,""],dup:[3,1,1,""],dupd:[3,1,1,""],dupdd:[3,1,1,""],first:[3,1,1,""],first_two:[3,1,1,""],fourth:[3,1,1,""],over:[3,1,1,""],pop:[3,1,1,""],popd:[3,1,1,""],popdd:[3,1,1,""],popop:[3,1,1,""],popopd:[3,1,1,""],popopdd:[3,1,1,""],rest:[3,1,1,""],rolldown:[3,1,1,""],rollup:[3,1,1,""],rrest:[3,1,1,""],second:[3,1,1,""],stack:[3,1,1,""],stuncons:[3,1,1,""],stununcons:[3,1,1,""],swap:[3,1,1,""],swons:[3,1,1,""],third:[3,1,1,""],tuck:[3,1,1,""],uncons:[3,1,1,""],unswons:[3,1,1,""]},"joy.utils.pretty_print":{TracePrinter:[19,2,1,""]},"joy.utils.pretty_print.TracePrinter":{go:[19,5,1,""],viewer:[19,5,1,""]},"joy.utils.stack":{concat:[20,1,1,""],expression_to_string:[20,1,1,""],iter_stack:[20,1,1,""],list_to_stack:[20,1,1,""],pick:[20,1,1,""],stack_to_string:[20,1,1,""]},joy:{joy:[1,0,0,"-"],library:[3,0,0,"-"],parser:[18,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","classmethod","Python class method"],"4":["py","exception","Python exception"],"5":["py","method","Python method"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:classmethod","4":"py:exception","5":"py:method"},terms:{"0b11100111011011":5,"23rd":15,"4b4cb6ff86e5":15,"5bkei":10,"5eb7ac5ad2c2":15,"\u03b5":8,"abstract":[7,10,17],"boolean":[2,3,7,10],"break":[7,15],"byte":5,"case":[2,3,12,14,15,20],"class":[3,7,15,18,19,20],"default":[3,6,10,20],"export":[3,18],"final":[2,10,12],"float":[3,7,15,16,18],"function":[0,1,4,5,6,9,11,16,17,18,19,20],"g\u00e9rard":16,"import":[2,5,6,8,10,11,12,13,14,15,16],"int":[6,7,12,15,16,18,20],"long":[10,17],"new":[2,3,6,7,9,12,13,15],"p\u00f6ial":17,"p\u00f6ial06typingtool":15,"public":9,"return":[1,3,5,7,10,12,13,14,15,18,19,20],"static":[2,9],"super":15,"switch":[2,15],"throw":10,"true":[2,3,5,12,15],"try":[6,8,11,12,14,15],"void":[0,3],"while":[3,7,10,15,18,20],Adding:[7,13,17],And:[5,6,8,10,12,15,16,20],But:[0,4,5,6,7,10,13,15],CPS:7,For:[2,3,10,12,13,15,17,20],Has:3,Its:3,One:[2,7,15,17],TOS:[2,3],That:[5,10],The:[0,1,2,3,4,6,8,9,11,15,16,17,18,20],Then:[2,3,10,11,12,15],There:[11,12,14,15,20],These:[15,17,20],Use:[3,8,12],Using:[0,8,10,17],With:[8,12,15,17],_1000:15,__add__:15,__class__:15,__eq__:15,__ge__:15,__hash__:15,__init__:15,__main__:15,__radd__:15,__repr__:15,__str__:19,_names_for:15,_to_str:15,_tree_add_:10,_tree_add_e:10,_tree_add_p:10,_tree_add_r:10,_tree_add_t:10,_tree_delete_:10,_tree_delete_clear_stuff:10,_tree_delete_del:10,_tree_delete_r0:10,_tree_delete_r1:10,_tree_delete_rightmost:10,_tree_delete_w:10,_tree_get_:10,_tree_get_p:10,_tree_get_r:10,_tree_get_t:10,_tree_iter_order_curr:10,_tree_iter_order_left:10,_tree_iter_order_r:10,_tree_iter_order_right:10,_tree_t:10,_treestep_0:14,_treestep_1:14,_uniqu:15,_within_b:8,_within_p:8,_within_r:8,a10001:15,a10002:15,a10003:15,a10004:15,a1001:[],abbrevi:14,abil:15,abl:15,about:[0,7,10,15,16,20],abov:[0,5,8,10,12,15],abs:8,absolut:7,accept:[1,2,3,5,6,7,10,11,13,14,15,16],accordingli:10,accumul:5,action:[7,13,15,16],actual:[2,5,7,10,15],adapt:17,add:[3,5,6,7,13,15,19],add_alias:3,add_def:3,add_definit:[3,10,14],added:[4,10],adding:[9,15],addit:[0,2,3,5,7,12,13,14],address:17,adjust:10,after:[5,6,7,12],afterward:7,again:[2,3,5,7,10,12,15],aggreg:16,ahead:15,aka:[7,16],albrecht:0,algorithm:[7,15],alia:3,alias:[3,7],align:[7,19],all:[3,5,6,7,10,12,13,14,15,19],alloc:15,allow:[9,10],almost:10,along:[7,12,15],alphabet:3,alreadi:[8,13,15,16],also:[0,5,7,10,15,20],alter:15,altern:[4,15],although:[4,10,15],altogeth:6,alwai:[5,9,12],amaz:15,among:15,amort:10,analysi:[4,17],anamorph:[7,17],ani:[4,5,7,9,10,15,16,18],annual:7,anonym:10,anoth:[10,15,20],anyhow:15,anyjoytyp:15,anymor:15,anystarjoytyp:15,anyth:[2,3,7,15],api:9,app1:3,app2:[3,7,11,12,13],app3:3,app:7,appear:[2,4,5,10],append:15,appendix:17,appli:[2,3,5,6,10,12,15],applic:6,approach:5,approxim:17,archiv:0,aren:16,arg:[2,3],argument:[2,3,7,8,11,12,17,19,20],arithmet:2,ariti:2,around:[5,15,20],arrang:14,arriv:[6,14],articl:[0,4,6,12],ask:[4,6,15],aspect:0,assert:15,assign:20,associ:10,assum:8,astar:15,asterisk:14,asterix:15,attack:7,attempt:[0,1],attribut:3,attributeerror:15,author:15,auto:0,automat:[4,15],auxiliari:14,avail:[0,15],averag:[7,13],avoid:10,awai:10,awar:2,awkward:[10,12],azur:17,back:[10,15],backward:[9,10,11,14],bag:7,banana:12,barb:12,base:[0,2,3,9,12,14,15],basic:[1,2,3,7,10],becaus:[2,3,7,10,14,15,16,20],becom:[10,14,20],becuas:15,been:[8,9,10,15,16],befor:[6,7,10],begin:[10,14],behavior:[9,14],behaviour:[0,1,15],being:0,below:[2,3,5,6,10,15,16],bespok:7,best:0,better:[5,10,12],between:[0,5],beyond:6,biannual:7,binari:[0,6,7,17],binary_search_tre:10,binarybuiltinwrapp:3,bind:7,bingo:16,bit:[5,6,10,15],block:5,bodi:[2,7,10],body_text:3,booktitl:15,bool:12,borrow:[7,15],both:[2,5,7,11,12,13,15,20],bottom:6,bracket:[7,15,18],branch:[3,5,6,12,15],breakpoint:7,bring:[5,7,15],bruijn:15,brzozowski:15,btree:[10,14],buck:10,bug:[0,7,15],build:[6,7,11,12,15,16,20],built:[11,15],bundl:[2,3,12],burgeon:7,calculu:4,call:[2,7,9,10,12,15,19,20],caller:10,can:[0,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,20],cannot:15,captur:7,card:7,care:[5,20],carefulli:16,carri:[6,10],cartesian:4,catamorph:17,categor:[0,17],categori:4,ccc:4,ccon:[3,10,15],cell:[12,15],certain:[7,20],certainli:10,chain:3,chang:[2,9,10,15,16],charact:16,chat:7,chatter:[0,15],check:[6,8,15],child:14,choic:[3,12],choos:9,chop:11,cinf:10,circuit:4,cite_not:10,classmethod:3,claus:[3,15],clean:15,clear:[3,5,7],clear_stuff:10,cleav:[7,11,13],close:[0,1,4],clunki:[5,15],cmp:[3,14,17],cmp_:3,code:[0,1,4,11,12,15,17],codireco:[6,8],collaps:12,collect:[4,6,7,15],combin:[0,3,5,6,7,8,11,14,16,17],combinatorjoytyp:15,come:[7,10,15],command:[7,10,15],common:[2,5],compar:[3,4,15],comparison:[0,10],compel:4,compil:[2,4,7,10,13,17],complet:[4,15],complex:[3,15,16],complic:15,composit:15,compostit:15,compound:10,comput:[2,4,5,7,11,15],con:[3,5,6,7,8,10,11,12,14,16,20],conal:4,concat:[3,6,7,14,20],concat_:3,concaten:0,concatin:[0,3,20],conclus:17,concurr:2,cond:[3,10],condit:[3,7],confer:15,conflict:[10,15],conjectur:15,consecut:17,consid:[5,6,10,12,14,15,16],consist:[2,6,7,14],constant:10,constitu:12,constraint:15,construct:15,consum:15,contain:[0,2,3,6,7,12,15],content:15,context:2,conting:10,continu:[0,12,15,16],control:7,conveni:[4,15],convers:15,convert:[12,13,14,15,18,20],cool:10,copi:[2,3,5,10,12,14,17],copyright:7,correct:15,correspond:4,could:[2,4,5,7,9,10,15,16],count:[3,15],counter:[5,15],coupl:14,cours:[5,10,15],cover:15,crack:10,crap:15,crash:10,creat:[0,2,3,5,8,10,15],creativ:15,crude:[10,15,18],currect:15,current:[2,3,7,12,14,15,16,19],custom:9,cycl:[5,6],cython:7,dai:7,data:[2,3,12],datastructur:[0,2,12,15,17,18,20],datatyp:20,ddee30dbb1a6:15,ddididi:16,deal:[0,10],dealt:15,decid:10,declar:15,decor:3,decoupl:12,decrement:3,deduc:[5,15],deeper:0,deepli:4,def:[3,7,12,13,15,20],defaultdict:15,defi:3,defin:[2,3,4,5,6,7,8,9,11,12,13,15,16,17],definit:[2,3,5,6,7,9,10,12,14,15,17],definitionwrapp:[3,10,12,14],deleg:7,delet:17,deliber:15,demonstr:4,depend:[3,10,12],deposit:14,depth:15,dequot:12,der:10,deriv:[2,3,5,7,8,10,15,17],describ:[3,4,10,12,14,15,18],descript:[5,7],descriptor:15,design:[2,3,10,17],desir:[7,14],destruct:10,detail:[7,10,15],detect:[6,10,12,15],determin:17,develop:[0,6,7,15,17],diagram:5,dialect:1,dict:[1,3,15],dictionari:[0,1,3,7,15,17],differ:[0,4,5,8,10,11,12,20],differenti:4,difficult:15,dig:[10,16],digit:5,dinfrirst:7,dip:[3,5,6,7,8,10,11,12,13,14,15,17],dip_a:15,dip_t:15,dipd:[3,6,7,10,11,12,15,16],dipdd:[3,10],direco:17,direct:7,directli:[5,14,15,20],disappear:[2,15],discard:[3,6,8,10,12],disciplin:10,disenstacken:7,disk:7,displac:2,displai:15,distiguish:15,ditch:10,div:[3,7],dive:14,divis:10,divmod:3,divmod_:[3,15],doc:[2,3,7,15],document:[17,18,20],doe:[0,1,4,6,7,13,17,19],doesn:[5,9,10,14,15,20],doing:[4,5,7,15,16],domain:[4,15],don:[5,7,10,15],done:[2,5,7,9,15],door:7,dot:19,doubl:[5,7,15],down:[2,8,12,15,16],down_to_zero:7,dozen:7,draft:[4,9],dream:7,drive:[6,8],driven:5,driver:6,drop:[3,10],dudipd:7,due:15,dup:[3,5,6,7,8,10,11,12,16,20],dupd:[3,15],dupdd:3,dupdip:[3,5,10,11,12],duplic:[3,10,12],durat:2,dure:[2,12],each:[2,3,4,5,7,12,13,14,15,19],easi:[0,10,14,15,16],easier:[3,10],easili:4,edit:17,effect:[2,3,7,16,17],effici:[6,13,16],either:[1,2,3,10,12,15],elabor:15,eleg:[7,10,15],element:2,elif:15,elimin:15,elliott:4,els:[2,3,12,15],embed:[4,10,16],emit:15,empti:[3,7,14,15,20],encapsul:7,enclos:7,encod:6,encount:15,end:[5,10,12,14,15,20],endless:6,enforc:[2,7],engend:7,enorm:15,enough:[7,12,15,19],enstacken:[6,7,15],enter:7,entir:20,entri:[3,16,19],enumer:15,epsilon:8,equal:[5,14,20],equat:[7,8],ergo:10,err:10,error:[7,15,18],essai:0,establish:15,etc:[3,14,15,16,18],euler:17,euro:15,eval:[0,15],evalu:[1,2,3,7,8,10,11,12,13,14,15],event:15,eventu:15,everi:[6,15],everyth:[3,10,11,15],evolv:9,examin:12,exampl:[0,3,5,15,17,18,20],exce:6,except:[7,10,15,18],execut:[0,1,2,3,7,12,13,14,15,16,20],exend:15,exercis:10,exist:[4,10,15],expand:10,expect:[2,3,14,15,20],experi:[7,14],explain:15,explan:7,explor:7,express:[0,1,2,3,4,10,12,13,15,16,19,20],expression_to_str:20,extend:15,extra:[5,6],extract:[10,11,17],extrem:7,extrememli:7,f1001:[],f_g:15,f_in:15,f_out:15,f_python:15,facet:0,facil:7,fact:18,factor:[2,5,7,10,15],factori:17,fail:[2,3,10,18],fairli:15,fale:15,fals:[2,3,5,12,15],far:[8,10,12,15],fascin:0,fear:[10,15],few:[5,7,8,11],fewer:[3,7],fg_in:15,fg_out:15,fib:6,fib_gen:6,fibonacci:17,figur:[2,3,10,12],filter:10,fin:5,find:[2,3,5,6,14,15,17],finder:8,fine:[0,5,10,15],first:[3,6,7,8,10,11,12,13,14,16,17],first_two:[3,10],fit:[5,7],five:[5,7,17],fix:[2,3,12],fixm:15,flatten:[7,14],flexibl:17,floatjoytyp:15,floatstarjoytyp:15,floor:3,floordiv:5,flow:7,follow:[0,2,3,7,9,12,14,15,16],foo:[7,9,10,15],foo_ii:9,form:[2,3,4,5,6,12,14,15,20],forman:7,format:[15,17,19],formula:[0,5,17],forth:[7,15],forum:0,forward:15,found:7,foundat:15,four:[2,3,5,6,7,10,17],fourteen:5,fourth:[2,3,10,12],fractal:7,fraction0:7,fraction:[2,7],frame:12,framework:7,free:[4,7,10],freeli:2,from:[0,1,2,3,5,6,7,8,10,11,12,13,14,15,16,17,20],front:[2,3,12],full:5,fulli:15,fun:17,func:15,functionwrapp:3,funtion:10,further:[8,15,17],g_in:15,g_out:15,garbag:7,gari:10,gcd:7,gener:[0,2,4,12,15,17,20],generated_librari:3,genrec:[3,7,10,12,14],geometr:5,get:[2,4,5,6,7,11,12,15,17],getitem:3,getrecursionlimit:20,getsourc:7,ghc:4,give:[4,5,10,12,14,15,20],given:[2,3,5,6,8,10,12,15,16,17],global:15,glue:7,going:[10,11,14,15,16],good:[5,10],grab:[3,15],grammar:18,grand:7,great:[0,7,15,17],greater:20,grok:15,group:0,gsra:8,guard:10,had:[5,15,16],haiku:7,half:[5,15,16],hand:[7,13,15,17],handi:[8,15],handl:[10,15,20],happen:[7,15],hard:[15,16],hardwar:4,has:[0,2,6,7,8,9,10,12,15,16,20],hash:15,haskel:4,have:[2,3,5,6,7,8,9,12,13,15,16,17,20],haven:15,head:20,help:[7,10,12,15],help_:3,helper:3,herd:7,here:[5,6,10,14,15,16],hide:10,hierarchi:15,higher:[7,10],highli:7,histori:[15,19],hmm:10,hoist:3,hold:[5,15],hood:10,hope:[0,5,7,15,17],hopefulli:12,host:17,how:[0,4,8,10,12,15,16,17],howev:[12,13,15],html:[2,3,6,11,12,17],http:10,huet:16,huge:10,hugh:[8,14],human:7,hybrid:15,hylomorph:17,hypothet:2,id_:3,idea:[4,5,7,15],ident:[3,12],if_not_empti:10,ift:[3,10,12,14,15],ignor:[3,10,15],iii:17,illustr:12,imagin:16,imap:15,imit:14,immedi:12,immut:[7,10],imper:12,implement:[0,1,2,3,4,7,9,10,12,13,17],impli:15,implicit:7,includ:[4,10,14,15],inclus:5,incom:20,incompat:9,incorpor:11,increas:5,increment:[3,4,5,9],index:[0,7,15,20],indexerror:20,indic:[14,15],ineffici:15,infer:[0,17],inform:[3,15],infra:[3,6,7,10,11,13,14,17],infrastructur:3,initi:[2,3,7,8,10],inlin:10,inner:15,inproceed:15,input:[1,8,15],inscrib:3,insert:15,insight:12,inspect:7,instal:0,instanti:[4,19],instead:[5,6,10,12,15,16,20],integ:[2,3,7,12,14,15],integr:3,intend:[0,7],interact:[7,17],interest:[0,5,10,15,17],interlud:17,intermedi:12,intern:[0,15,19,20],interpret:[0,4,9,13,17,18,19],interrupt:7,interv:[4,5],intjoytyp:15,introduc:9,introduct:0,intstarjoytyp:15,intuit:15,invari:3,invent:15,involv:15,ipf:7,ipython:15,isinst:15,isn:[10,16],issubclass:15,item:[2,3,7,10,12,14,15,17,20],iter:[1,3,7,12,14,15,17,20],iter_stack:[13,15,20],iteritem:15,itertool:15,its:[0,2,3,4,5,7,10,12,14,15,20],itself:[0,2,7,10,15],j05cmp:[2,3,12],jaanu:15,job:17,john:[8,14],joi:[2,4,9,10,11,13],join:15,joypi:[7,16],june:15,junk:17,jupyt:17,just:[0,2,3,6,7,9,10,12,14,15,16],kav:15,keep:[10,11,15,16],kei:[14,17],kevin:0,key_n:10,keyerror:[10,15],kind:[2,4,7,10,12,14,15],kinda:15,kjs:15,kleen:[14,15],kleenestar:15,kleffner:15,know:[5,10,15],knowledg:15,known:4,l_kei:10,l_left:10,l_right:10,l_valu:10,label:15,lambda:[4,15],languag:[4,7,9,10,13,15],larg:15,larger:20,largest:3,last:[5,10,12,15],lastli:6,later:[7,14,15],law:[2,15],lazi:15,lazili:8,lcm:5,lead:[7,15],leaf:10,lean:7,learn:0,least:[2,5,12,15,20],least_fract:7,leav:5,left:[7,11,12,14,15,16,19,20],leftov:12,len:15,length:[3,5,20],lens:12,less:[5,6,7,12,15,20],let:[6,8,10,11,12,14,15,16],letter:15,level:[4,10],librari:[0,13],like:[2,3,5,7,14,15,17,18],limit:15,line:[3,7,10,11,19],linear:20,link:0,linux:0,list:[0,3,5,7,8,10,12,14,16,19],list_to_stack:20,lit:15,liter:[1,10,14,15,16,18],literatur:15,littl:[6,10,15,17],live:17,lkei:14,load:[5,7],local:15,locat:2,locu:19,lof:15,log_2:10,logic:[0,5,17],longer:[10,15],look:[6,7,8,10,11,15],lookup:7,loop:[0,1,3,5],lose:15,lot:[7,10,16],love:5,low:4,lower:5,lowercas:15,lowest:10,machin:0,machineri:[10,15],macro:7,made:[0,7,15,16],magic:15,mai:[2,12,15],mail:0,main:[0,3,7,11,15,16],mainloop:9,maintain:16,major:9,make:[2,3,4,5,7,10,12,13,14,15,16,17],make_gener:8,manfr:[0,2,3,4,12],mani:[0,7,15],manipul:15,manner:11,map:[1,3,5,7,9,12,14,15],map_:3,marker:7,mask:[5,6],match:[0,1],materi:[0,15],math:[0,7,8,10,11,15],mathemat:7,matter:[5,8,10,14],max_:3,maximum:3,mayb:10,mean:[4,5,7,8,10,12,14,15,20],meant:[7,10,12,14],member:[2,3,12],mental:[7,15],mention:2,mercuri:0,mess:15,meta:[7,10,13],meta_compos:15,metal:15,method:[0,3,7,15,17,19],midpoint:5,might:[4,6,10,15],mike:10,million:6,min_:3,mind:15,minimum:3,minor:10,minu:3,mirror:0,miscellan:0,mix:[7,15],mod:3,mode:15,model:[4,7,15],modern:0,modif:6,modifi:[7,10,16],modul:[0,1,3,7,15,18],modulu:7,moment:15,month:7,more:[0,3,4,5,6,7,8,12,13,14,15,18,20],most:15,mostli:0,motiv:15,move:10,movement:2,much:[5,6,10,12,15],muck:10,mul:[7,11,16,19],multi:3,multipl:17,must:[2,3,5,9,12,14,15],myself:15,n10001:15,n10002:15,n10003:15,n1001:15,n1002:15,n1003:15,name:[1,3,7,9,10,12,15,16,17,18,20],natur:[5,6,10],navig:16,nearli:15,neat:10,neato:15,necessarili:15,need:[2,3,5,6,8,9,10,12,15],neg:[3,11],nest:[3,7,10,16],network:7,never:[9,12],new_def:15,new_f:15,new_kei:10,new_valu:10,newton:[0,17],next:[5,14,15],nice:[0,12,20],niether:2,node:[14,17],node_kei:10,node_valu:10,non:[14,15],none:[1,3,15],nope:14,notat:[7,10],note:[2,5,8,10,12,15,20],notebook:[5,6,7,15,16,17],notebook_preambl:[2,5,6,8,10,11,12,13,14,15,16],noth:[2,10],notic:5,now:[5,6,7,12,13,14,15,17],nth:[3,20],nullari:[7,10],number:[1,2,3,5,6,8,20],numberjoytyp:15,numberstarjoytyp:15,numer:15,object:[15,18],observ:5,obviou:6,obvious:15,occur:10,odd:[5,6],off:[2,3,5,6,11,16],okai:15,old:[2,13],old_k:10,old_kei:10,old_valu:10,omit:[12,15],onc:[3,9,10],one:[2,3,5,6,10,12,14,15,19,20],ones:[6,15],onli:[2,3,5,10,12,15,16,20],onto:[1,2,3,7,12,20],open:[7,15],oper:[3,7,10,12,15,20],oppos:15,optim:10,option:[1,7,10,20],order:[0,2,3,7,12,15,17,20],org:[0,10],origin:[0,1,2,3,10,15,16],other:[0,2,3,4,7,10,12,14,15,20],otherwis:[3,5,6,10,14,15],our:[5,6,7,8,12,14,15],out:[2,3,4,5,6,7,8,10,11,12,15,16],outcom:14,output:[8,12,15],outsid:4,over:[3,4,5,6,7,8,10,11,14,15,17],overhaul:15,overview:15,own:[10,15],pace:15,pack:20,packag:[0,7],page:[0,10,15,20],pair:[2,3,5,6,10,15],palidrom:5,palindrom:5,pam:7,paper:[4,7,12,16],paradigm:17,parallel:2,paramet:[1,2,3,12,13,18,19,20],parameter:17,paramorph:12,parenthes:[10,20],pariti:6,pars:[0,3,7],parse_definit:3,parseerror:18,parser:[0,15],part:[2,3,8,12,14,17],partial:15,particular:16,pass:[0,10,15,19],path:17,pattern:[5,14,17],pe1:[5,6],pe2:6,pearl:16,pend:[3,7,12,16,19],peopl:17,per:[7,14],perform:15,perhap:6,period:7,permit:[15,20],permut:15,persist:10,phase:2,pick:[5,6,20],pickl:7,pictur:10,piec:12,pip:0,place:[3,5,7,15],plai:0,plu:3,plug:[6,12,14],point:[4,7,10,12],pointless:2,pop:[3,5,6,7,10,12,13,14,20],popd:[3,7,8,10,13,15],popdd:[3,6,11,15],popop:[3,5,6,7,8,10,14,15],popopd:3,popopdd:3,posit:[3,5,7,12],possibilit:10,possibl:[10,14,15,17],post:7,poswrd:15,power:7,pragmat:5,preambl:8,precis:[0,1],pred:[3,15],predic:[2,3,6,12],prefix:[15,19],present:15,preserv:[4,14],pretti:[8,10,11,14,15,19,20],pretty_print:0,previou:7,primari:15,prime:8,primit:[2,3,15,17],primrec:[3,6,7,8,12],principl:15,print:[0,1,2,3,15,19,20],probabl:[6,7,10,15],problem:[7,15,17],proc_curr:10,proc_left:10,proc_right:10,proce:5,process:[7,14,15,19],produc:[5,10,12,14,15],product:[6,7,15],program:[0,2,3,6,7,8,10,12,15,16],programm:15,progress:15,project:17,prompt:7,proper:[2,3,12],properti:0,provabl:15,proven:15,provid:[0,3,4,7,15],pun:[0,7],punctuat:15,pure:0,puriti:7,purpos:7,push:[2,3,7,12,16,20],pushback:7,put:[1,2,6,7,15,17,20],pypi:0,python:[0,2,3,10,12,16,17,18,20],quadrat:[0,17],queri:[10,14],query_kei:14,queu:12,quit:[0,1,14],quot:[0,3,6,7,10,11,12,14,15,16,19],quotat:[2,3,12],quotient:3,r_kei:10,r_left:10,r_right:10,r_valu:10,rais:[10,15,18,20],rang:[7,15],range_revers:12,range_to_zero:7,ranger:12,ranger_revers:12,raphson:8,rather:[5,7,12,14],ratio:7,reach:[5,6,12],read:[0,1,5,6,10,15,16],readabl:13,reader:10,readi:15,real:10,realiz:[4,10],rearrang:[2,10,15],reason:[5,7,15],rebuild:[14,16],rec1:[2,3,12],rec2:[2,3,12],recent:15,recogn:18,record:[7,19],recur:[12,15],recurs:[0,2,3,6,7,8,15,17,20],recus:7,recycl:15,redefin:17,redistribut:[3,7],reduc:[2,15],redund:20,refactor:[7,9],refer:[0,2],regist:2,regular:[15,18],reimplement:17,relat:15,releas:9,remain:[2,7,9],remaind:[3,8],remind:15,remov:[3,10,15,20],render:17,repeat:5,repeatedli:5,repl:[0,1],replac:[0,2,3,6,11,12,14,15,16,17,20],repositori:0,repr:15,repres:[2,7,10,18,19],represent:20,reprod:6,repurpos:15,requir:[15,20],res:15,research:15,resembl:7,respect:5,rest:[3,5,6,7,10,12,16,17,20],rest_two:10,restat:15,restor:2,restrict:15,result:[1,2,3,5,10,11,12,14,15,16],resum:7,retain:15,retir:2,retri:7,reus:[10,15],revers:[3,5,6,12,15,16,20],revisit:15,rewrit:[3,7,15],rewritten:7,rich:15,rid:10,right:[6,7,11,14,15,17,19,20],rightest:10,rightmost:5,rkei:14,rob:15,robot:15,roll:[3,8,10,14],roll_dn:15,roll_down:15,roll_up:15,rolldown:3,rollup:3,root:[3,8,11],round:15,rrest:[3,15],rule:17,run:[0,1,3,5,7,8,10,11,12,14,16],runtimeerror:20,s1000:[],s1002:[],s23:[],sai:[6,10,11,14,15],same:[2,4,5,10,15,20],sandwich:[2,3,12],save:[2,5,7],scan:3,scanner:[7,18],scenario:16,scope:[6,10],search:[0,10],sec:15,second:[3,7,10,12,14,20],section:12,see:[0,6,7,8,9,11,12,13,15,16,19],seem:[0,5,7,14,15],seen:[15,16],select:3,self:15,semant:[2,3,7,9,10,15],semi:7,send:7,sens:[0,2,5,15,16],separ:[7,15],seq:15,sequenc:[0,1,2,3,5,7,10,12,13,16,17,18],sequence_to_stack:15,seri:[5,6,10,16],ses:15,set:[2,3,12,15,17],seven:[5,6],sever:[0,4,7,12],share:[3,7],shelf:2,shift:[5,6],shorter:17,shorthand:10,should:[2,3,5,10,12,15],shouldn:7,show:[4,16],shunt:[3,16],side:[10,15],signifi:[7,10],similar:[10,14,15],simon:7,simpl:[7,12,15,20],simplefunctionwrapp:[3,13,15],simpler:14,simplest:[15,17],simpli:4,simplifi:[5,10,16],sinc:[2,5,10,15],singl:[3,6,7,13,15,18],situ:10,situat:10,six:[5,6,7],sixti:[5,6],size:[7,17],skeptic:7,skip:15,slight:8,slightli:[10,12,15],smallest:3,smart:[10,15],softwar:[7,15],solei:2,solut:[5,6],solvabl:7,some:[2,3,6,7,10,12,14,15,17,20],somehow:[10,15],someth:[2,9,10,15],sometim:10,somewher:[10,17],sort:[3,10,15],sort_:3,sorta:15,sourc:[0,1,3,15,17,18,19,20],space:[5,19],span:5,spawn:15,special:[6,10,15,17],specif:[0,4],specifi:[10,15],speed:13,spell:14,sphinx:[17,20],spirit:[0,1,14],split:15,sqr:[7,8,11,16],sqrt:[3,8,15],squar:[3,8,15,18],stack:[0,1,3,5,6,8,10,11,12,13,14,16,17,18,19],stack_concat:15,stack_effect:15,stack_effect_com:15,stack_to_str:20,stacki:15,stackjoytyp:15,stackstarjoytyp:15,stage:14,stai:[0,1],stand:4,standard:[7,10],star:[14,15],stare:10,start:[5,6,7,8,10,12,14,15],state:7,statement:3,step:[3,5,7,10,13,15,16,17],still:[10,15],stop:10,storag:[5,10],store:[5,12],stori:12,str:[1,15,18,19,20],straightforward:[1,6,8,15,17],stream:5,stretch:10,string:[1,2,3,7,15,16,18,19,20],structur:[7,14,15,16,17,20],stuff:[10,15],stuncon:3,stununcon:3,style:[0,4,15],sub:9,subclass:7,subject:16,subset:15,substitut:[10,15],subtract:5,subtyp:17,succ:[3,15],succe:15,success:8,suffic:15,suffici:10,suffix:15,suggest:[4,10],suitabl:[3,4,5],sum:[3,6,7,11,12,13,14],sum_:[3,15],summand:5,sumtre:14,suppli:[10,18],support:[7,15,19,20],suspect:2,swaack:[3,11,13,16],swap:[3,5,6,7,8,10,12,13,14,16],swarm:15,swon:[3,6,7,12,14,15,16],swoncat:[6,7,8,12,14],swuncon:12,symbol:[2,3,15,16,17,18],symboljoytyp:15,symmetr:[5,10],syntact:7,syntax:[7,20],sys:20,system:[7,10,15],tabl:15,tag:15,tail:[10,15,17,20],take:[3,5,7,8,10,12,15,20],talk:[7,10,15,20],target:16,tast:4,tbd:7,tear:12,technic:2,techniqu:[4,16],technolog:2,temporari:16,ten:5,term:[1,2,7,8,12,15,17,18,20],termin:[2,3,12],ternari:7,test:[2,3,12],text:[0,1,3,15],text_to_express:[7,15,18],textual:7,than:[0,3,5,6,7,8,12,14,15,20],thei:[2,5,6,7,10,12,15,16,18,20],them:[2,3,5,6,10,12,15,16,17],themselv:15,theori:[2,3,12],therefor:[6,15],thi:[0,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20],thing:[2,6,10,12,15,16,18,20],think:[2,5,7,10,12,14,15],third:[3,6,7,10],thirti:5,those:[2,3,10,12,15,17],though:5,thought:7,thousand:5,thread:2,three:[2,3,5,7,10,11,14,15,17],through:[1,5,7,14,15,16,20],thun:[2,3,4,9,12],thunder:7,time:[3,5,7,8,10,12,15,16],titl:15,to_set:10,todai:7,todo:[7,18],togeth:[6,7,15,17],token:18,toler:17,too:[12,15],tool:[7,15],tooo:15,top:[2,3,7,12,15,19,20],total:5,tower:15,trace:[0,7,11,12,16,17,20],traceback:15,traceprint:19,track:[11,15,16],tracker:0,transform:4,translat:[4,11,15],trash:15,travers:[0,17],treasur:0,treat:[0,2,3,12,15,17],treatment:6,tree:[0,7,17],treegrind:17,treestep:[0,17],tri:5,triangular_numb:12,trick:[5,15],tricki:15,trobe:0,trove:0,truli:15,trust:15,truthi:[3,7],tuck:[3,7,15],tupl:[3,7,15,20],ture:15,turn:[2,3,15],twice:[10,12],two:[2,3,5,7,8,10,11,12,14,15,16,17,20],type:[0,1,4,7,10,12,17,18,19,20],typeerror:15,typeless:15,typic:[2,3,11,12],unari:7,unarybuiltinwrapp:3,unbalanc:[10,18],unchang:10,uncompil:15,uncon:[3,6,7,10,12,14,16],under:[2,3,7,10],underli:15,underscor:15,understand:[0,10,15],undistinguish:10,undocu:7,unend:15,unfinish:15,unfortun:20,unif:15,uniqu:[3,10,15],unit:[7,12],univers:[0,7,15],unnecessari:17,unnecesssari:15,unpack:[2,3,10,15,20],unpair:5,unquot:[7,14],unstack:[3,15],unswon:3,untangl:12,until:6,unus:5,unusu:10,updat:[0,17],usag:7,use:[0,2,3,4,5,6,7,8,9,10,11,12,13,14,16,17,20],used:[3,4,7,10,12,16,18,20],useful:[0,15],user:14,uses:[2,5,12],using:[3,6,10,11,12,14,16],usual:[0,2,12],util:[0,3,13,15],valid:15,valu:[0,2,3,5,7,8,11,12,13,14,15,17,20],value_n:10,valueerror:[15,20],variabl:[15,17],variant:10,variat:[12,17],varieti:[4,7],variou:0,vener:20,verbos:4,veri:[0,1,4,7,10,20],verifi:15,versa:[2,15],version:[0,1,2,6,9,14,16,17],via:7,vice:[2,15],view:[10,17],viewer:[1,7,9,19],vii:17,von:[0,2,3,4,12],wai:[0,2,3,4,5,7,12,13,15],wait:15,want:[2,5,6,8,10,12,15],warranti:[3,7],wash:7,wast:7,web:20,websit:[0,5],welcom:7,well:[0,4,7,8,10,15,18],were:[7,15,16],what:[2,3,4,7,10,12,14,15,19],whatev:[2,3,12,14,20],when:[5,6,7,10,12,15,16,18,20],where:[2,3,7,10,12,15,17,20],whether:12,which:[0,1,3,5,7,8,10,12,14,15,16,20],whole:[2,3,5,12,14,15],whose:6,why:[8,14],wiki:10,wikipedia:[0,10,16],wildli:7,wind:7,wire:12,within:[7,10,13,17],without:[2,7,10,11,15],won:[10,15,20],word:[0,3,5,7,12,16],work:[0,3,5,6,7,8,10,11,12,14,15,16,20],worth:5,would:[2,5,6,7,8,10,12,15,16,20],wrap:[3,7],wrapper:15,write:[4,8,10,12,14,15,16,17,20],written:[0,1,8,10,13,15,20],wrong:2,wrote:15,xrang:15,yang:15,year:[7,15],yet:[10,15,16],yield:[2,3,12,15,20],yin:17,you:[0,2,3,5,6,7,9,10,11,12,13,14,15,16,19,20],your:[2,3,7,12,15],yourself:[7,10],zero:[3,10,12,14,15,18,20],zip:[5,15],zip_:3,zipper:[0,17],zstr:16},titles:["Thun 0.2.0 Documentation","Joy Interpreter","Functions Grouped by, er, Function with Examples","Function Reference","Categorical Programming","Developing a Program in Joy","Using x to Generate Values","Thun: Joy in Python","Newton\u2019s method","No Updates","Treating Trees I: Ordered Binary Trees","Quadratic formula","Recursive Combinators","Replacing Functions in the Dictionary","Treating Trees II: treestep","Type Inference","Traversing Datastructures with Zippers","Essays about Programming in Joy","Parsing Text into Joy Expressions","Tracing Joy Execution","Stack or Quote or Sequence or List\u2026"],titleterms:{"abstract":15,"case":[8,10],"function":[2,3,7,8,10,12,13,14,15],"long":13,"new":10,"p\u00f6ial":15,"void":2,"while":2,Adding:10,One:[6,10],The:[5,7,10,12,14],There:7,Using:6,With:14,about:17,add:[2,10],adding:10,address:16,altern:14,ana:12,analysi:5,anamorph:[2,12],app1:2,app2:2,app3:2,appendix:[10,12,15],approxim:8,argument:15,auto:3,averag:2,base:[8,10],binari:[2,10,14],both:10,branch:[2,10],can:10,cata:12,catamorph:12,categor:4,chatter:2,child:10,choic:2,clear:2,cleav:2,cmp:10,code:[7,10],combin:[2,10,12,15],comment:15,compar:10,comparison:2,compil:[6,15],compile_:15,compos:15,comput:8,con:[2,15],concat:[2,15],conclus:12,consecut:8,continu:7,current:10,datastructur:[7,10,16],deal:15,defin:[10,14],definit:11,delabel:15,delet:10,deriv:[11,12,14],design:12,determin:16,develop:5,dialect:0,dictionari:13,dip:[2,16],dipd:2,dipdd:2,direco:6,disenstacken:2,distinguish:15,div:2,doc_from_stack_effect:15,document:0,doe:10,down_to_zero:2,drop:2,dup:[2,15],dupd:2,dupdip:2,effect:15,els:10,empti:10,enstacken:2,equal:10,essai:17,euler:[5,6],eval:7,even:6,exampl:[2,7,10,12,14],execut:19,express:[7,18],extract:14,factori:12,fibonacci:6,filter:5,find:[8,10,12],first:[2,5,15],five:6,flatten:2,flexibl:14,floordiv:2,formula:11,found:10,four:12,fun:12,further:5,gcd:2,gener:[3,5,6,8],genrec:2,get:[10,14],getitem:2,given:14,greater:10,group:2,have:[10,14],help:2,highest:10,host:0,how:[5,6],hylo:12,hylomorph:12,identifi:15,ift:2,iii:15,implement:15,indic:0,infer:15,inferenc:15,inform:0,infra:[2,16],integ:5,interest:6,interlud:10,intern:18,interpret:[1,7,15],item:16,iter:[5,10],joi:[0,1,3,5,7,12,15,16,17,18,19,20],junk:15,just:5,kei:10,languag:0,least_fract:2,left:10,less:10,let:5,librari:[3,7,15],like:10,list:[2,15,20],literari:7,littl:5,logic:[2,15],loop:[2,7],lower:10,lshift:2,make:[6,8],mani:5,map:2,math:2,method:8,min:2,miscellan:2,mod:2,modifi:15,modulu:2,more:10,most:10,mul:[2,15],multipl:[5,6,15],must:10,name:11,neg:2,newton:8,next:8,node:10,non:10,now:10,nullari:2,number:[12,15],one:7,onli:7,order:[10,14],osdn:0,our:10,over:2,pack:5,pam:2,para:12,paradigm:15,parameter:[10,14],pars:[2,18],parser:[7,18],part:15,pass:7,path:16,pattern:12,per:10,pop:[2,15],popd:2,popop:2,pow:2,power:6,pred:2,predic:[5,8,10,14],pretty_print:19,primit:12,primrec:2,print:7,problem:[5,6],process:10,product:2,program:[4,5,11,14,17],project:[0,5,6],pure:7,put:[10,11,14],python:[7,13,15],quadrat:11,quick:0,quot:[2,20],rang:[2,5,12],range_to_zero:2,read:7,recur:[8,10],recurs:[10,12,14],redefin:[10,14],refactor:[5,10],refer:3,regular:7,reimplement:14,relabel:15,rem:2,remaind:2,remov:2,render:5,repl:7,replac:[10,13],repres:15,reset:6,rest:[2,15],revers:2,right:[10,16],rightmost:10,roll:[2,15],rolldown:2,rollup:2,rshift:2,rule:15,run:[2,6],second:[2,15],select:2,sequenc:[6,15,20],set:[8,10],shorter:13,should:7,shunt:2,simplest:5,size:[2,13],someth:[],sourc:10,special:12,sqr:[2,15],sqrt:[2,11],stack:[2,7,15,20],start:0,step:[2,12,14],straightforward:11,structur:10,style:7,sub:[2,10],subtyp:15,succ:2,sum:[2,5],swaack:2,swap:[2,15],swon:2,swoncat:2,symbol:[7,12],tabl:0,tail:12,take:2,term:[5,6,14],ternari:2,text:18,than:10,them:11,thi:10,third:[2,15],three:6,thun:[0,7],time:[2,6],togeth:[10,11,14],token:7,toler:8,trace:[13,19],traceprint:7,travers:[10,14,16],treat:[10,14],tree:[10,14,16],treegrind:14,treestep:14,triangular:12,truediv:2,truthi:2,tuck:2,two:6,type:15,unari:2,unbound:15,uncon:[2,15],unifi:15,unit:2,unnecessari:5,unquot:2,unstack:2,updat:[9,15],use:15,util:[19,20],valu:[6,10],variabl:11,variat:6,version:[5,10,13,15],view:7,vii:15,within:8,word:2,write:11,xor:2,yin:15,zero:6,zip:2,zipper:16}}) \ No newline at end of file diff --git a/docs/sphinx_docs/notebooks/Types.rst b/docs/sphinx_docs/notebooks/Types.rst index 0385776..4a1a80d 100644 --- a/docs/sphinx_docs/notebooks/Types.rst +++ b/docs/sphinx_docs/notebooks/Types.rst @@ -2,9 +2,43 @@ Type Inference ============== -Cf. `"Type Inference in Stack-Based Programming +This notebook presents a simple type inferencer for Joy code. It can +infer the stack effect of most Joy expressions. It built largely by +means of existing ideas and research (some of it may be original but I'm +not able to say, as I don't fully understand the all of the source +material in the depth required to make that call.) A great overview of +the existing knowledge is a talk `"Type Inference in Stack-Based +Programming Languages" `__ -by Rob Kleffner, 2017-03-10. +given by Rob Kleffner on or about 2017-03-10 as part of a course on the +history of programming languages. + +The notebook starts with a simple inferencer based on the work of Jaanus +Pöial which we then progressively elaborate to cover more Joy semantics. +Along the way we write a simple "compiler" that emits Python code for +what I like to call Yin functions. + +Yin functions are those that only rearrange values in stacks, as opposed +to Yang functions that actually work on the values themselves. It's +interesting to note that a Joy with *only* stacks (no other kinds of +values) can be made and is Turing-complete, therefore all Yang functions +are actually Yin functions, and all computation can be performed by +manipulations of structures of containers, which is a restatement of the +Laws of Form. (Also, this implies that every program can be put into a +form such that it can be computed in a single step, although that step +may be enormous or unending.) + +Although I haven't completed it yet, a Joy based on Laws of Form +provides the foundation for a provably correct computing system "down to +the metal". This is my original and still primary motivation for +developing Joy. (I want a proven-correct Operating System for a swarm of +trash-collecting recycler robots. To trust it I have to implementment it +myself from first principles, and I'm not smart enough to truly grok the +existing literature and software, so I had to go look for and find LoF +and Joy. Now that I have the mental tools to build my robot OS I can get +down to it. + +Anyhow, here's type inference... Part I: Pöial's Rules --------------------- @@ -761,8 +795,8 @@ deal with this recursively: -Part III: Compiling Stack Functions ------------------------------------ +Part III: Compiling Yin Functions +--------------------------------- Now consider the Python function we would like to derive: @@ -1605,7 +1639,7 @@ also get the effect of combinators in some limited cases. .. code:: ipython2 - # e.g. [popop] dip + # e.g. [popop] dipd neato(popdd, roll_down, pop) @@ -1676,6 +1710,14 @@ such. Note that this is *not* a ``sqr`` function implementation: return (n1, stack) +(Eventually I should come back around to this becuase it's not tooo +difficult to exend this code to be able to compile e.g. +``n3 = mul(n1, n2)`` for ``mul`` and insert it in the right place with +the right variable names. It requires a little more support from the +library functions, in that we need to know to call ``mul()`` the Python +function for ``mul`` the Joy function, but since *most* of the math +functions (at least) are already wrappers it should be straightforward.) + ``compilable()`` ^^^^^^^^^^^^^^^^ @@ -2231,7 +2273,7 @@ While in the second it spawns an ``A``, which we will label ``e``: w/ {d: e} [ A* b .0.] U [ .1.] w/ {.1.: A* b .0.} - [ A* b .0.] U [ .1.] + [ A* b .0.] U [ A* b .0.] Giving us two unifiers: @@ -2601,19 +2643,20 @@ This function has to be modified to yield multiple results. Part VII: Typing Combinators ---------------------------- -TBD - -This is an open subject. - -The obvious thing is that you now need two pairs of tuples to describe -the combinators' effects, a stack effect comment and an expression -effect comment: +In order to compute the stack effect of combinators you kinda have to +have the quoted programs they expect available. In the most general +case, the ``i`` combinator, you can't say anything about it's stack +effect other than it expects one quote: :: - dip (a [F] --)--(-- F a) + i (... [.1.] -- ... .1.) -One thing that might help is... +Or + +:: + + i (... [A* .1.] -- ... A*) Consider the type of: @@ -2633,226 +2676,20 @@ Obviously it would be: (a1 [..1] -- ... then what? -.. code:: ipython2 - - class SymbolJoyType(AnyJoyType): prefix = 'F' - - W = map(SymbolJoyType, _R) - - k = S[0], ((W[1], S[2]), S[0]) - Symbol('cons') - print doc_from_stack_effect(*k) - - - -.. parsed-literal:: - - (-- [F1 .2.]) - - -.. code:: ipython2 - - dip_a = ((W[1], S[2]), (A[1], S[0])) - -.. code:: ipython2 - - d = relabel(S[0], dip_a) - print doc_from_stack_effect(*d) - - -.. parsed-literal:: - - (-- a1001 [F1001 .1002.]) - - -.. code:: ipython2 - - s = list(unify(d[1], k[1]))[0] - s - - - - -.. parsed-literal:: - - {s0: (a1001, s1000), s1002: s2, F1001: F1} - - - -.. code:: ipython2 - - j = update(s, k) - -.. code:: ipython2 - - print doc_from_stack_effect(*j) - - -.. parsed-literal:: - - (a1001 -- a1001 [F1 .2.]) - - -.. code:: ipython2 - - j - - - - -.. parsed-literal:: - - ((a1001, s1000), ((F1, s2), (a1001, s1000))) - - - -.. code:: ipython2 - - cons - - - - -.. parsed-literal:: - - ((s1, (a1, s23)), ((a1, s1), s23)) - - - -.. code:: ipython2 - - for f in MC([k], [dup]): - print doc_from_stack_effect(*f) - - -.. parsed-literal:: - - (-- [F0 .1.] [F0 .1.]) - - -.. code:: ipython2 - - l = S[0], ((cons, S[2]), (A[1], S[0])) - -.. code:: ipython2 - - print doc_from_stack_effect(*l) - - -.. parsed-literal:: - - (-- a1 [[[[.1.] a1 .23.] [a1 .1.] .23.] .2.]) - - -.. code:: ipython2 - - - def dip_t(F): - (quote, (a1, sec)) = F[1] - G = F[0], sec - P = S[3], (a1, S[3]) - a = [P] - while isinstance(quote, tuple): - term, quote = quote - a.append(term) - a.append(G) - return a[::-1] - - - - - -.. code:: ipython2 - - from joy.utils.stack import iter_stack - -.. code:: ipython2 - - a, b, c = dip_t(l) - -.. code:: ipython2 - - a - - - - -.. parsed-literal:: - - (s0, s0) - - - -.. code:: ipython2 - - b - - - - -.. parsed-literal:: - - ((s1, (a1, s23)), ((a1, s1), s23)) - - - -.. code:: ipython2 - - c - - - - -.. parsed-literal:: - - (s3, (a1, s3)) - - - -.. code:: ipython2 - - MC([a], [b]) - - - - -.. parsed-literal:: - - [((s0, (a0, s1)), ((a0, s0), s1))] - - - -.. code:: ipython2 - - kjs = MC(MC([a], [b]), [c]) - kjs - - - - -.. parsed-literal:: - - [((s0, (a0, s1)), (a1, ((a0, s0), s1)))] - - - -.. code:: ipython2 - - print doc_from_stack_effect(*kjs[0]) - - -.. parsed-literal:: - - (a0 [.0.] -- [a0 .0.] a1) - - -:: - - (a0 [.0.] -- [a0 .0.] a1) - - a0 [.0.] a1 [cons] dip - ---------------------------- - [a0 .0.] a1 +Without any information about the contents of the quote we can't say +much about the result. + +I think there's a way forward. If we convert our list of terms we are +composing into a stack structure we can use it as a *Joy expression*, +then we can treat the *output half* of a function's stack effect comment +as a Joy interpreter stack, and just execute combinators directly. We +can hybridize the compostition function with an interpreter to evaluate +combinators, compose non-combinator functions, and put type variables on +the stack. For combinators like ``branch`` that can have more than one +stack effect we have to "split universes" again and return both. (Note: +bug! If one branch doesn't type check the currect code ignores it, so +you can think things are okay but have a type error waiting in the faled +branch, I think... D'oh! FIXME!!!) .. code:: ipython2 @@ -2924,117 +2761,6 @@ the pace I should be able to verify that conjecture by the end of June. The rest of this stuff is junk and/or unfinished material. -``concat`` -~~~~~~~~~~ - -How to deal with ``concat``? - -:: - - concat ([.0.] [.1.] -- [.0. .1.]) - -We would like to represent this in Python somehow... - -.. code:: ipython2 - - concat = (S[0], S[1]), ((S[0], S[1]),) - -But this is actually ``cons`` with the first argument restricted to be a -stack: - -:: - - ([.0.] [.1.] -- [[.0.] .1.]) - -What we have implemented so far would actually only permit: - -:: - - ([.0.] [.1.] -- [.2.]) - -.. code:: ipython2 - - concat = (S[0], S[1]), (S[2],) - -Which works but can lose information. Consider ``cons concat``, this is -how much information we *could* retain: - -:: - - (1 [.0.] [.1.] -- [1 .0. .1.]) - -As opposed to just: - -:: - - (1 [.0.] [.1.] -- [.2.]) - -represent ``concat`` -~~~~~~~~~~~~~~~~~~~~ - -:: - - ([.0.] [.1.] -- [A*(.0.) .1.]) - -Meaning that ``A*`` on the right-hand side should all the crap from -``.0.``. - -:: - - ([ .0.] [.1.] -- [ A* .1.]) - ([a .0.] [.1.] -- [a A* .1.]) - ([a b .0.] [.1.] -- [a b A* .1.]) - ([a b c .0.] [.1.] -- [a b c A* .1.]) - -or... - -:: - - ([ .0.] [.1.] -- [ .1.]) - ([a .0.] [.1.] -- [a .1.]) - ([a b .0.] [.1.] -- [a b .1.]) - ([a b c .0.] [.1.] -- [a b c .1.]) - ([a A* c .0.] [.1.] -- [a A* c .1.]) - -:: - - (a, (b, S0)) . S1 = (a, (b, (A*, S1))) - -.. code:: ipython2 - - class Astar(object): - def __repr__(self): - return 'A*' - - - def concat(s0, s1): - a = [] - while isinstance(s0, tuple): - term, s0 = s0 - a.append(term) - assert isinstance(s0, StackJoyType), repr(s0) - s1 = Astar(), s1 - for term in reversed(a): - s1 = term, s1 - return s1 - -.. code:: ipython2 - - a, b = (A[1], S[0]), (A[2], S[1]) - -.. code:: ipython2 - - concat(a, b) - - - - -.. parsed-literal:: - - (a1, (A*, (a2, s1))) - - - Appendix: Joy in the Logical Paradigm ------------------------------------- @@ -3056,7 +2782,7 @@ For this to work the type label classes have to be modified to let ValueError Traceback (most recent call last) - in () + in () 1 F = reduce(C, (pop, swap, roll_down, rest, rest, cons, cons)) 2 ----> 3 print doc_from_stack_effect(*F) @@ -3174,3 +2900,221 @@ function... In any event "mixed-mode" interpreters that include values and type variables and can track constraints, etc. will be, uh, super-useful. And Abstract Interpretation should be a rich source of ideas. + +Junk +---- + +.. code:: ipython2 + + class SymbolJoyType(AnyJoyType): prefix = 'F' + + W = map(SymbolJoyType, _R) + + k = S[0], ((W[1], S[2]), S[0]) + Symbol('cons') + print doc_from_stack_effect(*k) + + +.. code:: ipython2 + + dip_a = ((W[1], S[2]), (A[1], S[0])) + +.. code:: ipython2 + + d = relabel(S[0], dip_a) + print doc_from_stack_effect(*d) + +.. code:: ipython2 + + s = list(unify(d[1], k[1]))[0] + s + +.. code:: ipython2 + + j = update(s, k) + +.. code:: ipython2 + + print doc_from_stack_effect(*j) + +.. code:: ipython2 + + j + +.. code:: ipython2 + + cons + +.. code:: ipython2 + + for f in MC([k], [dup]): + print doc_from_stack_effect(*f) + +.. code:: ipython2 + + l = S[0], ((cons, S[2]), (A[1], S[0])) + +.. code:: ipython2 + + print doc_from_stack_effect(*l) + +.. code:: ipython2 + + + def dip_t(F): + (quote, (a1, sec)) = F[1] + G = F[0], sec + P = S[3], (a1, S[3]) + a = [P] + while isinstance(quote, tuple): + term, quote = quote + a.append(term) + a.append(G) + return a[::-1] + + + + + +.. code:: ipython2 + + from joy.utils.stack import iter_stack + +.. code:: ipython2 + + a, b, c = dip_t(l) + +.. code:: ipython2 + + a + +.. code:: ipython2 + + b + +.. code:: ipython2 + + c + +.. code:: ipython2 + + MC([a], [b]) + +.. code:: ipython2 + + kjs = MC(MC([a], [b]), [c]) + kjs + +.. code:: ipython2 + + print doc_from_stack_effect(*kjs[0]) + +:: + + (a0 [.0.] -- [a0 .0.] a1) + + a0 [.0.] a1 [cons] dip + ---------------------------- + [a0 .0.] a1 + +``concat`` +~~~~~~~~~~ + +How to deal with ``concat``? + +:: + + concat ([.0.] [.1.] -- [.0. .1.]) + +We would like to represent this in Python somehow... + +.. code:: ipython2 + + concat = (S[0], S[1]), ((S[0], S[1]),) + +But this is actually ``cons`` with the first argument restricted to be a +stack: + +:: + + ([.0.] [.1.] -- [[.0.] .1.]) + +What we have implemented so far would actually only permit: + +:: + + ([.0.] [.1.] -- [.2.]) + +.. code:: ipython2 + + concat = (S[0], S[1]), (S[2],) + +Which works but can lose information. Consider ``cons concat``, this is +how much information we *could* retain: + +:: + + (1 [.0.] [.1.] -- [1 .0. .1.]) + +As opposed to just: + +:: + + (1 [.0.] [.1.] -- [.2.]) + +represent ``concat`` +~~~~~~~~~~~~~~~~~~~~ + +:: + + ([.0.] [.1.] -- [A*(.0.) .1.]) + +Meaning that ``A*`` on the right-hand side should all the crap from +``.0.``. + +:: + + ([ .0.] [.1.] -- [ A* .1.]) + ([a .0.] [.1.] -- [a A* .1.]) + ([a b .0.] [.1.] -- [a b A* .1.]) + ([a b c .0.] [.1.] -- [a b c A* .1.]) + +or... + +:: + + ([ .0.] [.1.] -- [ .1.]) + ([a .0.] [.1.] -- [a .1.]) + ([a b .0.] [.1.] -- [a b .1.]) + ([a b c .0.] [.1.] -- [a b c .1.]) + ([a A* c .0.] [.1.] -- [a A* c .1.]) + +:: + + (a, (b, S0)) . S1 = (a, (b, (A*, S1))) + +.. code:: ipython2 + + class Astar(object): + def __repr__(self): + return 'A*' + + + def concat(s0, s1): + a = [] + while isinstance(s0, tuple): + term, s0 = s0 + a.append(term) + assert isinstance(s0, StackJoyType), repr(s0) + s1 = Astar(), s1 + for term in reversed(a): + s1 = term, s1 + return s1 + +.. code:: ipython2 + + a, b = (A[1], S[0]), (A[2], S[1]) + +.. code:: ipython2 + + concat(a, b)