OSDN Git Service

Convert syntax highlighter spec.
authorSimon Forman <sforman@hushmail.com>
Fri, 19 Nov 2021 21:57:36 +0000 (13:57 -0800)
committerSimon Forman <sforman@hushmail.com>
Fri, 19 Nov 2021 21:57:36 +0000 (13:57 -0800)
12 files changed:
docs/sphinx_docs/notebooks/Derivatives_of_Regular_Expressions.rst
docs/sphinx_docs/notebooks/Developing.rst
docs/sphinx_docs/notebooks/Generator_Programs.rst
docs/sphinx_docs/notebooks/Intro.rst
docs/sphinx_docs/notebooks/Ordered_Binary_Trees.rst
docs/sphinx_docs/notebooks/Quadratic.rst
docs/sphinx_docs/notebooks/Recursion_Combinators.rst
docs/sphinx_docs/notebooks/Replacing.rst
docs/sphinx_docs/notebooks/Treestep.rst
docs/sphinx_docs/notebooks/TypeChecking.rst
docs/sphinx_docs/notebooks/Types.rst
docs/sphinx_docs/notebooks/Zipper.rst

index 29dc9fb..bbcbb73 100644 (file)
@@ -76,7 +76,7 @@ E.g.:
 Implementation
 --------------
 
-.. code:: ipython2
+.. code:: python
 
     from functools import partial as curry
     from itertools import product
@@ -86,7 +86,7 @@ Implementation
 
 The empty set and the set of just the empty string.
 
-.. code:: ipython2
+.. code:: python
 
     phi = frozenset()   # ϕ
     y = frozenset({''}) # λ
@@ -101,7 +101,7 @@ alphabet with two symbols (if you had to.)
 I chose the names ``O`` and ``l`` (uppercase “o” and lowercase “L”) to
 look like ``0`` and ``1`` (zero and one) respectively.
 
-.. code:: ipython2
+.. code:: python
 
     syms = O, l = frozenset({'0'}), frozenset({'1'})
 
@@ -123,7 +123,7 @@ expression* is one of:
 
 Where ``R`` and ``S`` stand for *regular expressions*.
 
-.. code:: ipython2
+.. code:: python
 
     AND, CONS, KSTAR, NOT, OR = 'and cons * not or'.split()  # Tags are just strings.
 
@@ -133,7 +133,7 @@ only, these datastructures are immutable.
 String Representation of RE Datastructures
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     def stringy(re):
         '''
@@ -175,11 +175,11 @@ Match anything. Often spelled “.”
 
    I = (0|1)*
 
-.. code:: ipython2
+.. code:: python
 
     I = (KSTAR, (OR, O, l))
 
-.. code:: ipython2
+.. code:: python
 
     print stringy(I)
 
@@ -201,14 +201,14 @@ The example expression from Brzozowski:
 
 Note that it contains one of everything.
 
-.. code:: ipython2
+.. code:: python
 
     a = (CONS, I, (CONS, l, (CONS, l, (CONS, l, I))))
     b = (CONS, I, (CONS, O, l))
     c = (CONS, l, (KSTAR, l))
     it = (AND, a, (NOT, (OR, b, c)))
 
-.. code:: ipython2
+.. code:: python
 
     print stringy(it)
 
@@ -223,7 +223,7 @@ Note that it contains one of everything.
 
 Let’s get that auxiliary predicate function ``δ`` out of the way.
 
-.. code:: ipython2
+.. code:: python
 
     def nully(R):
         '''
@@ -263,7 +263,7 @@ This is the straightforward version with no “compaction”. It works fine,
 but does waaaay too much work because the expressions grow each
 derivation.
 
-.. code:: ipython2
+.. code:: python
 
     def D(symbol):
     
@@ -308,7 +308,7 @@ derivation.
 Compaction Rules
 ~~~~~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     def _compaction_rule(relation, one, zero, a, b):
         return (
@@ -320,7 +320,7 @@ Compaction Rules
 
 An elegant symmetry.
 
-.. code:: ipython2
+.. code:: python
 
     # R ∧ I = I ∧ R = R
     # R ∧ ϕ = ϕ ∧ R = ϕ
@@ -341,7 +341,7 @@ We can save re-processing by remembering results we have already
 computed. RE datastructures are immutable and the ``derv()`` functions
 are *pure* so this is fine.
 
-.. code:: ipython2
+.. code:: python
 
     class Memo(object):
     
@@ -365,7 +365,7 @@ With “Compaction”
 This version uses the rules above to perform compaction. It keeps the
 expressions from growing too large.
 
-.. code:: ipython2
+.. code:: python
 
     def D_compaction(symbol):
     
@@ -414,7 +414,7 @@ Let’s try it out…
 
 (FIXME: redo.)
 
-.. code:: ipython2
+.. code:: python
 
     o, z = D_compaction('0'), D_compaction('1')
     REs = set()
@@ -605,20 +605,20 @@ You can see the one-way nature of the ``g`` state and the ``hij`` “trap”
 in the way that the ``.111.`` on the left-hand side of the ``&``
 disappears once it has been matched.
 
-.. code:: ipython2
+.. code:: python
 
     from collections import defaultdict
     from pprint import pprint
     from string import ascii_lowercase
 
-.. code:: ipython2
+.. code:: python
 
     d0, d1 = D_compaction('0'), D_compaction('1')
 
 ``explore()``
 ~~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     def explore(re):
     
@@ -645,7 +645,7 @@ disappears once it has been matched.
     
         return table, accepting
 
-.. code:: ipython2
+.. code:: python
 
     table, accepting = explore(it)
     table
@@ -678,7 +678,7 @@ disappears once it has been matched.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     accepting
 
@@ -697,7 +697,7 @@ Generate Diagram
 Once we have the FSM table and the set of accepting states we can
 generate the diagram above.
 
-.. code:: ipython2
+.. code:: python
 
     _template = '''\
     digraph finite_state_machine {
@@ -722,7 +722,7 @@ generate the diagram above.
               )
             )
 
-.. code:: ipython2
+.. code:: python
 
     print make_graph(table, accepting)
 
@@ -776,7 +776,7 @@ Trampoline Function
 Python has no GOTO statement but we can fake it with a “trampoline”
 function.
 
-.. code:: ipython2
+.. code:: python
 
     def trampoline(input_, jump_from, accepting):
         I = iter(input_)
@@ -793,7 +793,7 @@ Stream Functions
 Little helpers to process the iterator of our data (a “stream” of “1”
 and “0” characters, not bits.)
 
-.. code:: ipython2
+.. code:: python
 
     getch = lambda I: int(next(I))
     
@@ -816,7 +816,7 @@ code. (You have to imagine that these are GOTO statements in C or
 branches in assembly and that the state names are branch destination
 labels.)
 
-.. code:: ipython2
+.. code:: python
 
     a = lambda I: c if getch(I) else b
     b = lambda I: _0(I) or d
@@ -833,12 +833,12 @@ Note that the implementations of ``h`` and ``g`` are identical ergo
 ``h = g`` and we could eliminate one in the code but ``h`` is an
 accepting state and ``g`` isn’t.
 
-.. code:: ipython2
+.. code:: python
 
     def acceptable(input_):
         return trampoline(input_, a, {h, i})
 
-.. code:: ipython2
+.. code:: python
 
     for n in range(2**5):
         s = bin(n)[2:]
index 5b9314b..556225a 100644 (file)
@@ -12,7 +12,7 @@ As an example of developing a program in Joy let's take the first problem from t
 
     Find the sum of all the multiples of 3 or 5 below 1000.
 
-.. code:: ipython2
+.. code:: python
 
     from notebook_preamble import J, V, define
 
@@ -22,11 +22,11 @@ Sum a range filtered by a predicate
 Let's create a predicate that returns ``True`` if a number is a multiple
 of 3 or 5 and ``False`` otherwise.
 
-.. code:: ipython2
+.. code:: python
 
     define('P == [3 % not] dupdip 5 % not or')
 
-.. code:: ipython2
+.. code:: python
 
     V('80 P')
 
@@ -108,11 +108,11 @@ the counter to the running sum. This function will do that:
 
     PE1.1 == + [+] dupdip
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1.1 == + [+] dupdip')
 
-.. code:: ipython2
+.. code:: python
 
     V('0 0 3 PE1.1')
 
@@ -131,7 +131,7 @@ the counter to the running sum. This function will do that:
         3 3 . 
 
 
-.. code:: ipython2
+.. code:: python
 
     V('0 0 [3 2 1 3 1 2 3] [PE1.1] step')
 
@@ -219,7 +219,7 @@ total to 60.
 How many multiples to sum?
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. code:: ipython2
+.. code:: python
 
     1000 / 15
 
@@ -232,7 +232,7 @@ How many multiples to sum?
 
 
 
-.. code:: ipython2
+.. code:: python
 
     66 * 15
 
@@ -245,7 +245,7 @@ How many multiples to sum?
 
 
 
-.. code:: ipython2
+.. code:: python
 
     1000 - 990
 
@@ -260,7 +260,7 @@ How many multiples to sum?
 
 We only want the terms *less than* 1000.
 
-.. code:: ipython2
+.. code:: python
 
     999 - 990
 
@@ -276,11 +276,11 @@ We only want the terms *less than* 1000.
 That means we want to run the full list of numbers sixty-six times to
 get to 990 and then the first four numbers 3 2 1 3 to get to 999.
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1 == 0 0 66 [[3 2 1 3 1 2 3] [PE1.1] step] times [3 2 1 3] [PE1.1] step pop')
 
-.. code:: ipython2
+.. code:: python
 
     J('PE1')
 
@@ -305,7 +305,7 @@ integer terms from the list.
         3  2  1  3  1  2  3
     0b 11 10 01 11 01 10 11 == 14811
 
-.. code:: ipython2
+.. code:: python
 
     0b11100111011011
 
@@ -318,11 +318,11 @@ integer terms from the list.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1.2 == [3 & PE1.1] dupdip 2 >>')
 
-.. code:: ipython2
+.. code:: python
 
     V('0 0 14811 PE1.2')
 
@@ -349,7 +349,7 @@ integer terms from the list.
                  3 3 3702 . 
 
 
-.. code:: ipython2
+.. code:: python
 
     V('3 3 3702 PE1.2')
 
@@ -376,7 +376,7 @@ integer terms from the list.
                  8 5 925 . 
 
 
-.. code:: ipython2
+.. code:: python
 
     V('0 0 14811 7 [PE1.2] times pop')
 
@@ -518,11 +518,11 @@ integer terms from the list.
 
 And so we have at last:
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1 == 0 0 66 [14811 7 [PE1.2] times pop] times 14811 4 [PE1.2] times popop')
 
-.. code:: ipython2
+.. code:: python
 
     J('PE1')
 
@@ -542,17 +542,17 @@ Let's refactor
       14811 n [PE1.2] times pop
     n 14811 swap [PE1.2] times pop
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1.3 == 14811 swap [PE1.2] times pop')
 
 Now we can simplify the definition above:
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop')
 
-.. code:: ipython2
+.. code:: python
 
     J('PE1')
 
@@ -581,11 +581,11 @@ then four more. In the *Generator Programs* notebook we derive a
 generator that can be repeatedly driven by the ``x`` combinator to
 produce a stream of the seven numbers repeating over and over again.
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1.terms == [0 swap [dup [pop 14811] [] branch [3 &] dupdip 2 >>] dip rest cons]')
 
-.. code:: ipython2
+.. code:: python
 
     J('PE1.terms 21 [x] times')
 
@@ -598,7 +598,7 @@ produce a stream of the seven numbers repeating over and over again.
 We know from above that we need sixty-six times seven then four more
 terms to reach up to but not over one thousand.
 
-.. code:: ipython2
+.. code:: python
 
     J('7 66 * 4 +')
 
@@ -611,7 +611,7 @@ terms to reach up to but not over one thousand.
 Here they are...
 ~~~~~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     J('PE1.terms 466 [x] times pop')
 
@@ -624,7 +624,7 @@ Here they are...
 ...and they do sum to 999.
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     J('[PE1.terms 466 [x] times pop] run sum')
 
@@ -638,7 +638,7 @@ Now we can use ``PE1.1`` to accumulate the terms as we go, and then
 ``pop`` the generator and the counter from the stack when we're done,
 leaving just the sum.
 
-.. code:: ipython2
+.. code:: python
 
     J('0 0 PE1.terms 466 [x [PE1.1] dip] times popop')
 
@@ -654,7 +654,7 @@ A little further analysis renders iteration unnecessary.
 Consider finding the sum of the positive integers less than or equal to
 ten.
 
-.. code:: ipython2
+.. code:: python
 
     J('[10 9 8 7 6 5 4 3 2 1] sum')
 
@@ -686,11 +686,11 @@ positive integers is:
 (The formula also works for odd values of N, I'll leave that to you if
 you want to work it out or you can take my word for it.)
 
-.. code:: ipython2
+.. code:: python
 
     define('F == dup ++ * 2 floordiv')
 
-.. code:: ipython2
+.. code:: python
 
     V('10 F')
 
@@ -727,7 +727,7 @@ And ending with:
 
 If we reverse one of these two blocks and sum pairs...
 
-.. code:: ipython2
+.. code:: python
 
     J('[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip')
 
@@ -737,7 +737,7 @@ If we reverse one of these two blocks and sum pairs...
     [[978 15] [980 12] [981 10] [984 9] [985 6] [987 5] [990 3]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map')
 
@@ -750,7 +750,7 @@ If we reverse one of these two blocks and sum pairs...
 (Interesting that the sequence of seven numbers appears again in the
 rightmost digit of each term.)
 
-.. code:: ipython2
+.. code:: python
 
     J('[ 3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map sum')
 
@@ -771,7 +771,7 @@ additional unpaired terms between 990 and 1000:
 So we can give the "sum of all the multiples of 3 or 5 below 1000" like
 so:
 
-.. code:: ipython2
+.. code:: python
 
     J('6945 33 * [993 995 996 999] cons sum')
 
index 55e1679..a59df18 100644 (file)
@@ -3,7 +3,7 @@ Using ``x`` to Generate Values
 
 Cf. jp-reprod.html
 
-.. code:: ipython2
+.. code:: python
 
     from notebook_preamble import J, V, define
 
@@ -57,7 +57,7 @@ We can make a generator for the Natural numbers (0, 1, 2, …) by using
 
 Let’s try it:
 
-.. code:: ipython2
+.. code:: python
 
     V('[0 swap [dup ++] dip rest cons] x')
 
@@ -81,7 +81,7 @@ Let’s try it:
 After one application of ``x`` the quoted program contains ``1`` and
 ``0`` is below it on the stack.
 
-.. code:: ipython2
+.. code:: python
 
     J('[0 swap [dup ++] dip rest cons] x x x x x pop')
 
@@ -94,11 +94,11 @@ After one application of ``x`` the quoted program contains ``1`` and
 ``direco``
 ----------
 
-.. code:: ipython2
+.. code:: python
 
     define('direco == dip rest cons')
 
-.. code:: ipython2
+.. code:: python
 
     V('[0 swap [dup ++] direco] x')
 
@@ -149,13 +149,13 @@ Reading from the bottom up:
    G == [direco] cons [swap] swap concat cons
    G == [direco] cons [swap] swoncat cons
 
-.. code:: ipython2
+.. code:: python
 
     define('G == [direco] cons [swap] swoncat cons')
 
 Let’s try it out:
 
-.. code:: ipython2
+.. code:: python
 
     J('0 [dup ++] G')
 
@@ -165,7 +165,7 @@ Let’s try it out:
     [0 swap [dup ++] direco]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('0 [dup ++] G x x x pop')
 
@@ -178,7 +178,7 @@ Let’s try it out:
 Powers of 2
 ~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     J('1 [dup 1 <<] G x x x x x x x x x pop')
 
@@ -194,7 +194,7 @@ Powers of 2
 If we have one of these quoted programs we can drive it using ``times``
 with the ``x`` combinator.
 
-.. code:: ipython2
+.. code:: python
 
     J('23 [dup ++] G 5 [x] times')
 
@@ -226,11 +226,11 @@ int:
 And pick them off by masking with 3 (binary 11) and then shifting the
 int right two bits.
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1.1 == dup [3 &] dip 2 >>')
 
-.. code:: ipython2
+.. code:: python
 
     V('14811 PE1.1')
 
@@ -252,7 +252,7 @@ int right two bits.
 
 If we plug ``14811`` and ``[PE1.1]`` into our generator form…
 
-.. code:: ipython2
+.. code:: python
 
     J('14811 [PE1.1] G')
 
@@ -264,7 +264,7 @@ If we plug ``14811`` and ``[PE1.1]`` into our generator form…
 
 …we get a generator that works for seven cycles before it reaches zero:
 
-.. code:: ipython2
+.. code:: python
 
     J('[14811 swap [PE1.1] direco] 7 [x] times')
 
@@ -280,11 +280,11 @@ Reset at Zero
 We need a function that checks if the int has reached zero and resets it
 if so.
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1.1.check == dup [pop 14811] [] branch')
 
-.. code:: ipython2
+.. code:: python
 
     J('14811 [PE1.1.check PE1.1] G')
 
@@ -294,7 +294,7 @@ if so.
     [14811 swap [PE1.1.check PE1.1] direco]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times')
 
@@ -316,7 +316,7 @@ In the PE1 problem we are asked to sum all the multiples of three and
 five less than 1000. It’s worked out that we need to use all seven
 numbers sixty-six times and then four more.
 
-.. code:: ipython2
+.. code:: python
 
     J('7 66 * 4 +')
 
@@ -328,7 +328,7 @@ numbers sixty-six times and then four more.
 
 If we drive our generator 466 times and sum the stack we get 999.
 
-.. code:: ipython2
+.. code:: python
 
     J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times')
 
@@ -338,7 +338,7 @@ If we drive our generator 466 times and sum the stack we get 999.
     3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 [57 swap [PE1.1.check PE1.1] direco]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum')
 
@@ -351,13 +351,13 @@ If we drive our generator 466 times and sum the stack we get 999.
 Project Euler Problem One
 -------------------------
 
-.. code:: ipython2
+.. code:: python
 
     define('PE1.2 == + dup [+] dip')
 
 Now we can add ``PE1.2`` to the quoted program given to ``G``.
 
-.. code:: ipython2
+.. code:: python
 
     J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')
 
@@ -445,15 +445,15 @@ Putting it all together:
    F == + [popdd over] cons infra uncons
    fib_gen == [1 1 F]
 
-.. code:: ipython2
+.. code:: python
 
     define('fib == + [popdd over] cons infra uncons')
 
-.. code:: ipython2
+.. code:: python
 
     define('fib_gen == [1 1 fib]')
 
-.. code:: ipython2
+.. code:: python
 
     J('fib_gen 10 [x] times')
 
@@ -473,14 +473,14 @@ Now that we have a generator for the Fibonacci sequence, we need a
 function that adds a term in the sequence to a sum if it is even, and
 ``pop``\ s it otherwise.
 
-.. code:: ipython2
+.. code:: python
 
     define('PE2.1 == dup 2 % [+] [pop] branch')
 
 And a predicate function that detects when the terms in the series
 “exceed four million”.
 
-.. code:: ipython2
+.. code:: python
 
     define('>4M == 4000000 >')
 
@@ -488,11 +488,11 @@ Now it’s straightforward to define ``PE2`` as a recursive function that
 generates terms in the Fibonacci sequence until they exceed four million
 and sums the even ones.
 
-.. code:: ipython2
+.. code:: python
 
     define('PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec')
 
-.. code:: ipython2
+.. code:: python
 
     J('PE2')
 
@@ -535,7 +535,7 @@ So the Fibonacci sequence considered in terms of just parity would be:
 
 Every third term is even.
 
-.. code:: ipython2
+.. code:: python
 
     J('[1 0 fib] x x x')  # To start the sequence with 1 1 2 3 instead of 1 2 3.
 
@@ -547,7 +547,7 @@ Every third term is even.
 
 Drive the generator three times and ``popop`` the two odd terms.
 
-.. code:: ipython2
+.. code:: python
 
     J('[1 0 fib] x x x [popop] dipd')
 
@@ -557,11 +557,11 @@ Drive the generator three times and ``popop`` the two odd terms.
     2 [3 2 fib]
 
 
-.. code:: ipython2
+.. code:: python
 
     define('PE2.2 == x x x [popop] dipd')
 
-.. code:: ipython2
+.. code:: python
 
     J('[1 0 fib] 10 [PE2.2] times')
 
@@ -574,7 +574,7 @@ Drive the generator three times and ``popop`` the two odd terms.
 Replace ``x`` with our new driver function ``PE2.2`` and start our
 ``fib`` generator at ``1 0``.
 
-.. code:: ipython2
+.. code:: python
 
     J('0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec')
 
@@ -593,11 +593,11 @@ modifications to the default ``x``?
 An Interesting Variation
 ------------------------
 
-.. code:: ipython2
+.. code:: python
 
     define('codireco == cons dip rest cons')
 
-.. code:: ipython2
+.. code:: python
 
     V('[0 [dup ++] codireco] x')
 
@@ -620,11 +620,11 @@ An Interesting Variation
              0 [1 [dup ++] codireco] . 
 
 
-.. code:: ipython2
+.. code:: python
 
     define('G == [codireco] cons cons')
 
-.. code:: ipython2
+.. code:: python
 
     J('230 [dup ++] G 5 [x] times pop')
 
index b832048..73704cf 100644 (file)
@@ -150,7 +150,7 @@ TBD (look in the :module: joy.parser  module.)
 Examples
 ~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     joy.parser.text_to_expression('1 2 3 4 5')  # A simple sequence.
 
@@ -160,7 +160,7 @@ Examples
     (1, (2, (3, (4, (5, ())))))
 
 
-.. code:: ipython2
+.. code:: python
 
     joy.parser.text_to_expression('[1 2 3] 4 5')  # Three items, the first is a list with three items
 
@@ -170,7 +170,7 @@ Examples
     ((1, (2, (3, ()))), (4, (5, ())))
 
 
-.. code:: ipython2
+.. code:: python
 
     joy.parser.text_to_expression('1 23 ["four" [-5.0] cons] 8888')  # A mixed bag. cons is
                                                                      # a Symbol, no lookup at
@@ -184,7 +184,7 @@ Examples
 
 
 
-.. code:: ipython2
+.. code:: python
 
     joy.parser.text_to_expression('[][][][][]')  # Five empty lists.
 
@@ -197,7 +197,7 @@ Examples
 
 
 
-.. code:: ipython2
+.. code:: python
 
     joy.parser.text_to_expression('[[[[[]]]]]')  # Five nested lists.
 
@@ -221,7 +221,7 @@ provide control-flow and higher-order operations.
 
 Many of the functions are defined in Python, like ``dip``:
 
-.. code:: ipython2
+.. code:: python
 
     print inspect.getsource(joy.library.dip)
 
@@ -239,7 +239,7 @@ When the interpreter executes a definition function that function just
 pushes its body expression onto the pending expression (the
 continuation) and returns control to the interpreter.
 
-.. code:: ipython2
+.. code:: python
 
     print joy.library.definitions
 
index 569d665..a625ac3 100644 (file)
@@ -36,7 +36,7 @@ implementation under the hood. (Where does the “type” come from? It has
 a contingent existence predicated on the disciplined use of these
 functions on otherwise undistinguished Joy datastructures.)
 
-.. code:: ipython2
+.. code:: python
 
     from notebook_preamble import D, J, V, define, DefinitionWrapper
 
@@ -87,11 +87,11 @@ Definition:
 
    Tree-new == swap [[] []] cons cons
 
-.. code:: ipython2
+.. code:: python
 
     define('Tree-new == swap [[] []] cons cons')
 
-.. code:: ipython2
+.. code:: python
 
     J('"v" "k" Tree-new')
 
@@ -163,11 +163,11 @@ comparison operator:
    P < == pop roll> pop first <
    P   == pop roll> pop first
 
-.. code:: ipython2
+.. code:: python
 
     define('P == pop roll> pop first')
 
-.. code:: ipython2
+.. code:: python
 
     J('["old_key" 23 [] []] 17 "new_key" ["..."] P')
 
@@ -242,11 +242,11 @@ And so ``T`` is just:
 
    T == cons cons [dipdd] cons infra
 
-.. code:: ipython2
+.. code:: python
 
     define('T == cons cons [dipdd] cons infra')
 
-.. code:: ipython2
+.. code:: python
 
     J('["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] T')
 
@@ -266,7 +266,7 @@ This is very very similar to the above:
    [key_n value_n left right] value key [Tree-add] E
    [key_n value_n left right] value key [Tree-add] [P <] [Te] [Ee] ifte
 
-.. code:: ipython2
+.. code:: python
 
     define('E == [P <] [Te] [Ee] ifte')
 
@@ -278,11 +278,11 @@ instead of the right, so the only difference is that it must use
 
    Te == cons cons [dipd] cons infra
 
-.. code:: ipython2
+.. code:: python
 
     define('Te == cons cons [dipd] cons infra')
 
-.. code:: ipython2
+.. code:: python
 
     J('["old_k" "old_value" "left" "right"] "new_value" "new_key" ["Tree-add"] Te')
 
@@ -320,11 +320,11 @@ Example:
    key new_value [              left right]                                     cons cons
                  [key new_value left right]
 
-.. code:: ipython2
+.. code:: python
 
     define('Ee == pop swap roll< rest rest cons cons')
 
-.. code:: ipython2
+.. code:: python
 
     J('["k" "old_value" "left" "right"] "new_value" "k" ["Tree-add"] Ee')
 
@@ -355,14 +355,14 @@ Putting it all together:
 
    Tree-add == [popop not] [[pop] dipd Tree-new] [] [R] genrec
 
-.. code:: ipython2
+.. code:: python
 
     define('Tree-add == [popop not] [[pop] dipd Tree-new] [] [[P >] [T] [E] ifte] genrec')
 
 Examples
 ~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     J('[] 23 "b" Tree-add')  # Initial
 
@@ -372,7 +372,7 @@ Examples
     ['b' 23 [] []]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('["b" 23 [] []] 88 "c" Tree-add')  # Greater than
 
@@ -382,7 +382,7 @@ Examples
     ['b' 23 [] ['c' 88 [] []]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('["b" 23 [] []] 88 "a" Tree-add')  # Less than
 
@@ -392,7 +392,7 @@ Examples
     ['b' 23 ['a' 88 [] []] []]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('["b" 23 [] []] 88 "b" Tree-add')  # Equal to
 
@@ -402,7 +402,7 @@ Examples
     ['b' 88 [] []]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add')  # Series.
 
@@ -412,7 +412,7 @@ Examples
     ['b' 23 ['a' 88 [] []] ['c' 44 [] []]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[] [[23 "b"] [88 "a"] [44 "c"]] [i Tree-add] step')
 
@@ -444,7 +444,7 @@ values:
    ------------------------- a < b
                    L
 
-.. code:: ipython2
+.. code:: python
 
     J("1 0 ['G'] ['E'] ['L'] cmp")
 
@@ -454,7 +454,7 @@ values:
     'G'
 
 
-.. code:: ipython2
+.. code:: python
 
     J("1 1 ['G'] ['E'] ['L'] cmp")
 
@@ -464,7 +464,7 @@ values:
     'E'
 
 
-.. code:: ipython2
+.. code:: python
 
     J("0 1 ['G'] ['E'] ['L'] cmp")
 
@@ -514,7 +514,7 @@ Or just:
 
    P == over [popop popop first] nullary
 
-.. code:: ipython2
+.. code:: python
 
     define('P == over [popop popop first] nullary')
 
@@ -541,11 +541,11 @@ to understand:
 
    Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec
 
-.. code:: ipython2
+.. code:: python
 
     define('Tree-add == [popop not] [[pop] dipd Tree-new] [] [P [T] [Ee] [Te] cmp] genrec')
 
-.. code:: ipython2
+.. code:: python
 
     J('[] 23 "b" Tree-add 88 "a" Tree-add 44 "c" Tree-add')  # Still works.
 
@@ -685,14 +685,14 @@ Working backward:
 
    Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec
 
-.. code:: ipython2
+.. code:: python
 
     define('Tree-iter == [not] [pop] roll< [dupdip rest rest] cons [step] genrec')
 
 Examples
 ~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     J('[] [foo] Tree-iter')  #  It doesn't matter what F is as it won't be used.
 
@@ -702,7 +702,7 @@ Examples
     
 
 
-.. code:: ipython2
+.. code:: python
 
     J("['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [first] Tree-iter")
 
@@ -712,7 +712,7 @@ Examples
     'b' 'a' 'c'
 
 
-.. code:: ipython2
+.. code:: python
 
     J("['b' 23 ['a' 88 [] []] ['c' 44 [] []]] [second] Tree-iter")
 
@@ -731,7 +731,7 @@ to it will only occur once within it, and we can query it in
 `:math:`O(\log_2 N)` <https://en.wikipedia.org/wiki/Binary_search_tree#cite_note-2>`__
 time.
 
-.. code:: ipython2
+.. code:: python
 
     J('[] [3 9 5 2 8 6 7 8 4] [0 swap Tree-add] step')
 
@@ -741,11 +741,11 @@ time.
     [3 0 [2 0 [] []] [9 0 [5 0 [4 0 [] []] [8 0 [6 0 [] [7 0 [] []]] []]] []]]
 
 
-.. code:: ipython2
+.. code:: python
 
     define('to_set == [] swap [0 swap Tree-add] step')
 
-.. code:: ipython2
+.. code:: python
 
     J('[3 9 5 2 8 6 7 8 4] to_set')
 
@@ -758,11 +758,11 @@ time.
 And with that we can write a little program ``unique`` to remove
 duplicate items from a list.
 
-.. code:: ipython2
+.. code:: python
 
     define('unique == [to_set [first] Tree-iter] cons run')
 
-.. code:: ipython2
+.. code:: python
 
     J('[3 9 3 5 2 9 8 8 8 6 2 7 8 4 3] unique')  # Filter duplicate items.
 
@@ -872,7 +872,7 @@ Let’s do a little semantic factoring:
 
 Now we can sort sequences.
 
-.. code:: ipython2
+.. code:: python
 
     #define('Tree-iter-order == [not] [pop] [dup third] [[cons dip] dupdip [[first] dupdip] dip [rest rest rest first] dip i] genrec')
     
@@ -892,7 +892,7 @@ Now we can sort sequences.
     
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[3 9 5 2 8 6 7 8 4] to_set Tree-iter-order')
 
@@ -1070,7 +1070,7 @@ So:
 
    Tree-get == [pop not] swap [] [P [T>] [E] [T<] cmp] genrec
 
-.. code:: ipython2
+.. code:: python
 
     # I don't want to deal with name conflicts with the above so I'm inlining everything here.
     # The original Joy system has "hide" which is a meta-command which allows you to use named
@@ -1088,7 +1088,7 @@ So:
       ] genrec
     ''')
 
-.. code:: ipython2
+.. code:: python
 
     J('["gary" 23 [] []] "mike" [popd " not in tree" +] Tree-get')
 
@@ -1098,7 +1098,7 @@ So:
     'mike not in tree'
 
 
-.. code:: ipython2
+.. code:: python
 
     J('["gary" 23 [] []] "gary" [popop "err"] Tree-get')
 
@@ -1108,7 +1108,7 @@ So:
     23
 
 
-.. code:: ipython2
+.. code:: python
 
     J('''
     
@@ -1124,7 +1124,7 @@ So:
     2
 
 
-.. code:: ipython2
+.. code:: python
 
     J('''
     
@@ -1500,7 +1500,7 @@ Refactoring
 By the standards of the code I’ve written so far, this is a *huge* Joy
 program.
 
-.. code:: ipython2
+.. code:: python
 
     DefinitionWrapper.add_definitions('''
     first_two == uncons uncons pop
@@ -1519,7 +1519,7 @@ program.
     Tree-Delete == [pop not] [pop] [R0] [R1] genrec
     ''', D)
 
-.. code:: ipython2
+.. code:: python
 
     J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'c' Tree-Delete ")
 
@@ -1529,7 +1529,7 @@ program.
     ['a' 23 [] ['b' 88 [] []]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'b' Tree-Delete ")
 
@@ -1539,7 +1539,7 @@ program.
     ['a' 23 [] ['c' 44 [] []]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'a' Tree-Delete ")
 
@@ -1549,7 +1549,7 @@ program.
     ['b' 88 [] ['c' 44 [] []]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J("['a' 23 [] ['b' 88 [] ['c' 44 [] []]]] 'der' Tree-Delete ")
 
@@ -1559,7 +1559,7 @@ program.
     ['a' 23 [] ['b' 88 [] ['c' 44 [] []]]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[] [4 2 3 1 6 7 5 ] [0 swap Tree-add] step')
 
@@ -1569,7 +1569,7 @@ program.
     [4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J("[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 3 Tree-Delete ")
 
@@ -1579,7 +1579,7 @@ program.
     [4 0 [2 0 [1 0 [] []] []] [6 0 [5 0 [] []] [7 0 [] []]]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J("[4 0 [2 0 [1 0 [] []] [3 0 [] []]] [6 0 [5 0 [] []] [7 0 [] []]]] 4 Tree-Delete ")
 
index 3262e84..5afb8e2 100644 (file)
@@ -1,4 +1,4 @@
-.. code:: ipython2
+.. code:: python
 
     from notebook_preamble import J, V, define
 
@@ -81,13 +81,13 @@ the variables:
 The three arguments are to the left, so we can “chop off” everything to
 the right and say it’s the definition of the ``quadratic`` function:
 
-.. code:: ipython2
+.. code:: python
 
     define('quadratic == over [[[neg] dupdip sqr 4] dipd * * - sqrt pm] dip 2 * [/] cons app2')
 
 Let’s try it out:
 
-.. code:: ipython2
+.. code:: python
 
     J('3 1 1 quadratic')
 
@@ -102,7 +102,7 @@ lines are the ``dip`` and ``dipd`` combinators building the main program
 by incorporating the values on the stack. Then that program runs and you
 get the results. This is pretty typical of Joy code.
 
-.. code:: ipython2
+.. code:: python
 
     V('-5 1 4 quadratic')
 
index 9159882..65c4480 100644 (file)
@@ -1,4 +1,4 @@
-.. code:: ipython2
+.. code:: python
 
     from notebook_preamble import D, DefinitionWrapper, J, V, define
 
@@ -80,7 +80,7 @@ is a recursive function ``H :: A -> C`` that converts a value of type
 It may be helpful to see this function implemented in imperative Python
 code.
 
-.. code:: ipython2
+.. code:: python
 
     def hylomorphism(c, F, P, G):
         '''Return a hylomorphism function H.'''
@@ -185,7 +185,7 @@ the left so we have a definition for ``hylomorphism``:
 
    hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec
 
-.. code:: ipython2
+.. code:: python
 
     define('hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec')
 
@@ -203,13 +203,13 @@ To sum a range of integers from 0 to *n* - 1:
 -  ``[G]`` is ``[-- dup]``
 -  ``[F]`` is ``[+]``
 
-.. code:: ipython2
+.. code:: python
 
     define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')
 
 Let’s try it:
 
-.. code:: ipython2
+.. code:: python
 
     J('5 triangular_number')
 
@@ -219,7 +219,7 @@ Let’s try it:
     10
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[0 1 2 3 4 5 6] [triangular_number] map')
 
@@ -405,11 +405,11 @@ Each of the above variations can be used to make four slightly different
    H1 == [P]    [pop c]  [G]      [dip F]     genrec
       == [0 <=] [pop []] [-- dup] [dip swons] genrec
 
-.. code:: ipython2
+.. code:: python
 
     define('range == [0 <=] [] [-- dup] [swons] hylomorphism')
 
-.. code:: ipython2
+.. code:: python
 
     J('5 range')
 
@@ -427,11 +427,11 @@ Each of the above variations can be used to make four slightly different
    H2 == c  swap [P]    [pop] [G      [F]     dip] primrec
       == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec
 
-.. code:: ipython2
+.. code:: python
 
     define('range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec')
 
-.. code:: ipython2
+.. code:: python
 
     J('5 range_reverse')
 
@@ -449,11 +449,11 @@ Each of the above variations can be used to make four slightly different
    H3 == [P]    [pop c]  [[G]  dupdip] [dip F]     genrec
       == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec
 
-.. code:: ipython2
+.. code:: python
 
     define('ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec')
 
-.. code:: ipython2
+.. code:: python
 
     J('5 ranger')
 
@@ -471,11 +471,11 @@ Each of the above variations can be used to make four slightly different
    H4 == c  swap [P]    [pop] [[F]     dupdip G ] primrec
       == [] swap [0 <=] [pop] [[swons] dupdip --] primrec
 
-.. code:: ipython2
+.. code:: python
 
     define('ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec')
 
-.. code:: ipython2
+.. code:: python
 
     J('5 ranger_reverse')
 
@@ -501,7 +501,7 @@ and makes some new value.
 
    C == [not] c [uncons swap] [F] hylomorphism
 
-.. code:: ipython2
+.. code:: python
 
     define('swuncons == uncons swap')  # Awkward name.
 
@@ -511,11 +511,11 @@ An example of a catamorphism is the sum function.
 
    sum == [not] 0 [swuncons] [+] hylomorphism
 
-.. code:: ipython2
+.. code:: python
 
     define('sum == [not] 0 [swuncons] [+] hylomorphism')
 
-.. code:: ipython2
+.. code:: python
 
     J('[5 4 3 2 1] sum')
 
@@ -531,7 +531,7 @@ The ``step`` combinator
 The ``step`` combinator will usually be better to use than
 ``catamorphism``.
 
-.. code:: ipython2
+.. code:: python
 
     J('[step] help')
 
@@ -560,11 +560,11 @@ The ``step`` combinator will usually be better to use than
     
 
 
-.. code:: ipython2
+.. code:: python
 
     define('sum == 0 swap [+] step')
 
-.. code:: ipython2
+.. code:: python
 
     J('[5 4 3 2 1] sum')
 
@@ -592,11 +592,11 @@ With:
    G == --
    P == 1 <=
 
-.. code:: ipython2
+.. code:: python
 
     define('factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec')
 
-.. code:: ipython2
+.. code:: python
 
     J('5 factorial')
 
@@ -635,11 +635,11 @@ We would use:
    G == rest dup
    P == not
 
-.. code:: ipython2
+.. code:: python
 
     define('tails == [] swap [not] [pop] [rest dup [swons] dip] primrec')
 
-.. code:: ipython2
+.. code:: python
 
     J('[1 2 3] tails')
 
index 0f90445..02ecb3b 100644 (file)
@@ -9,14 +9,14 @@ dictionary. However, there’s no function that does that. Adding a new
 function to the dictionary is a meta-interpreter action, you have to do
 it in Python, not Joy.
 
-.. code:: ipython2
+.. code:: python
 
     from notebook_preamble import D, J, V
 
 A long trace
 ------------
 
-.. code:: ipython2
+.. code:: python
 
     V('[23 18] average')
 
@@ -81,7 +81,7 @@ An efficient ``sum`` function is already in the library. But for
 ``size`` we can use a “compiled” version hand-written in Python to speed
 up evaluation and make the trace more readable.
 
-.. code:: ipython2
+.. code:: python
 
     from joy.library import SimpleFunctionWrapper
     from joy.utils.stack import iter_stack
@@ -99,7 +99,7 @@ up evaluation and make the trace more readable.
 Now we replace the old version in the dictionary with the new version,
 and re-evaluate the expression.
 
-.. code:: ipython2
+.. code:: python
 
     D['size'] = size
 
@@ -108,7 +108,7 @@ A shorter trace
 
 You can see that ``size`` now executes in a single step.
 
-.. code:: ipython2
+.. code:: python
 
     V('[23 18] average')
 
index 6b9081f..7f273d8 100644 (file)
@@ -148,11 +148,11 @@ Working backwards:
 Define ``treestep``
 -------------------
 
-.. code:: ipython2
+.. code:: python
 
     from notebook_preamble import D, J, V, define, DefinitionWrapper
 
-.. code:: ipython2
+.. code:: python
 
     DefinitionWrapper.add_definitions('''
     
@@ -173,7 +173,7 @@ all nodes in a tree with this function:
 
    sumtree == [pop 0] [] [sum +] treestep
 
-.. code:: ipython2
+.. code:: python
 
     define('sumtree == [pop 0] [] [sum +] treestep')
 
@@ -185,7 +185,7 @@ Running this function on an empty tree value gives zero:
    ------------------------------------
               0
 
-.. code:: ipython2
+.. code:: python
 
     J('[] sumtree')  # Empty tree.
 
@@ -205,7 +205,7 @@ Running it on a non-empty node:
    n m                                             +
    n+m
 
-.. code:: ipython2
+.. code:: python
 
     J('[23] sumtree')  # No child trees.
 
@@ -215,7 +215,7 @@ Running it on a non-empty node:
     23
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[23 []] sumtree')  # Child tree, empty.
 
@@ -225,7 +225,7 @@ Running it on a non-empty node:
     23
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[23 [2 [4]] [3]] sumtree')  # Non-empty child trees.
 
@@ -235,7 +235,7 @@ Running it on a non-empty node:
     32
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[23 [2 [8] [9]] [3] [4 []]] sumtree')  # Etc...
 
@@ -245,7 +245,7 @@ Running it on a non-empty node:
     49
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[23 [2 [8] [9]] [3] [4 []]] [pop 0] [] [cons sum] treestep')  # Alternate "spelling".
 
@@ -255,7 +255,7 @@ Running it on a non-empty node:
     49
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 23] [cons] treestep')  # Replace each node.
 
@@ -265,7 +265,7 @@ Running it on a non-empty node:
     [23 [23 [23] [23]] [23] [23 []]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep')
 
@@ -275,7 +275,7 @@ Running it on a non-empty node:
     [1 [1 [1] [1]] [1] [1 []]]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[23 [2 [8] [9]] [3] [4 []]] [] [pop 1] [cons] treestep sumtree')
 
@@ -285,7 +285,7 @@ Running it on a non-empty node:
     6
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[23 [2 [8] [9]] [3] [4 []]] [pop 0] [pop 1] [sum +] treestep')  # Combine replace and sum into one function.
 
@@ -295,7 +295,7 @@ Running it on a non-empty node:
     6
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[4 [3 [] [7]]] [pop 0] [pop 1] [sum +] treestep')  # Combine replace and sum into one function.
 
@@ -339,7 +339,7 @@ Traversal
 
 This doesn’t quite work:
 
-.. code:: ipython2
+.. code:: python
 
     J('[[3 0] [[2 0] [][]] [[9 0] [[5 0] [[4 0] [][]] [[8 0] [[6 0] [] [[7 0] [][]]][]]][]]] ["B"] [first] [i] treestep')
 
@@ -369,7 +369,7 @@ So:
 
    [] [first] [flatten cons] treestep
 
-.. code:: ipython2
+.. code:: python
 
     J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]]   [] [first] [flatten cons] treestep')
 
@@ -401,7 +401,7 @@ So:
 
    [] [i roll< swons concat] [first] treestep
 
-.. code:: ipython2
+.. code:: python
 
     J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]]   [] [uncons pop] [i roll< swons concat] treestep')
 
@@ -429,7 +429,7 @@ Plugging in our BTree structure:
 
    [key value] N [left right] [K] C
 
-.. code:: ipython2
+.. code:: python
 
     J('[["key" "value"] ["left"] ["right"] ] ["B"] ["N"] ["C"] treegrind')
 
@@ -444,7 +444,7 @@ Plugging in our BTree structure:
 
 Iteration through the nodes
 
-.. code:: ipython2
+.. code:: python
 
     J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]]   [pop] ["N"] [step] treegrind')
 
@@ -456,7 +456,7 @@ Iteration through the nodes
 
 Sum the nodes’ keys.
 
-.. code:: ipython2
+.. code:: python
 
     J('0 [[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]]   [pop] [first +] [step] treegrind')
 
@@ -468,7 +468,7 @@ Sum the nodes’ keys.
 
 Rebuild the tree using ``map`` (imitating ``treestep``.)
 
-.. code:: ipython2
+.. code:: python
 
     J('[[3 0] [[2 0] [] []] [[9 0] [[5 0] [[4 0] [] []] [[8 0] [[6 0] [] [[7 0] [] []]] []]] []]]   [] [[100 +] infra] [map cons] treegrind')
 
@@ -574,7 +574,7 @@ Putting it together
 
 To me, that seems simpler than the ``genrec`` version.
 
-.. code:: ipython2
+.. code:: python
 
     DefinitionWrapper.add_definitions('''
     
@@ -587,7 +587,7 @@ To me, that seems simpler than the ``genrec`` version.
     
     ''', D)
 
-.. code:: ipython2
+.. code:: python
 
     J('''\
     
@@ -603,7 +603,7 @@ To me, that seems simpler than the ``genrec`` version.
     15
 
 
-.. code:: ipython2
+.. code:: python
 
     J('''\
     
index cd85c67..4e70a1a 100644 (file)
@@ -1,7 +1,7 @@
 Type Checking
 =============
 
-.. code:: ipython2
+.. code:: python
 
     import logging, sys
     
@@ -11,7 +11,7 @@ Type Checking
       level=logging.INFO,
       )
 
-.. code:: ipython2
+.. code:: python
 
     from joy.utils.types import (
         doc_from_stack_effect, 
@@ -22,7 +22,7 @@ Type Checking
         JoyTypeError,
     )
 
-.. code:: ipython2
+.. code:: python
 
     D = FUNCTIONS.copy()
     del D['product']
@@ -31,7 +31,7 @@ Type Checking
 An Example
 ----------
 
-.. code:: ipython2
+.. code:: python
 
     fi, fo = infer(pop, swap, rolldown, rrest, ccons)[0]
 
@@ -46,7 +46,7 @@ An Example
      40 ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1]) ∘ 
 
 
-.. code:: ipython2
+.. code:: python
 
     print doc_from_stack_effect(fi, fo)
 
@@ -56,13 +56,13 @@ An Example
     ([a4 a5 ...1] a3 a2 a1 -- [a2 a3 ...1])
 
 
-.. code:: ipython2
+.. code:: python
 
     from joy.parser import text_to_expression
     from joy.utils.stack import stack_to_string
 
 
-.. code:: ipython2
+.. code:: python
 
     e = text_to_expression('0 1 2 [3 4]')  # reverse order
     print stack_to_string(e)
@@ -73,7 +73,7 @@ An Example
     [3 4] 2 1 0
 
 
-.. code:: ipython2
+.. code:: python
 
     u = unify(e, fi)[0]
     u
@@ -87,7 +87,7 @@ An Example
 
 
 
-.. code:: ipython2
+.. code:: python
 
     g = reify(u, (fi, fo))
     print doc_from_stack_effect(*g)
@@ -101,11 +101,11 @@ An Example
 Unification Works “in Reverse”
 ------------------------------
 
-.. code:: ipython2
+.. code:: python
 
     e = text_to_expression('[2 3]')
 
-.. code:: ipython2
+.. code:: python
 
     u = unify(e, fo)[0]  # output side, not input side
     u
@@ -119,7 +119,7 @@ Unification Works “in Reverse”
 
 
 
-.. code:: ipython2
+.. code:: python
 
     g = reify(u, (fi, fo))
     print doc_from_stack_effect(*g)
@@ -133,7 +133,7 @@ Unification Works “in Reverse”
 Failing a Check
 ---------------
 
-.. code:: ipython2
+.. code:: python
 
     fi, fo = infer(dup, mul)[0]
 
@@ -146,7 +146,7 @@ Failing a Check
      31 (i1 -- i2) ∘ 
 
 
-.. code:: ipython2
+.. code:: python
 
     e = text_to_expression('"two"')
     print stack_to_string(e)
@@ -157,7 +157,7 @@ Failing a Check
     'two'
 
 
-.. code:: ipython2
+.. code:: python
 
     try:
         unify(e, fi)
index 4c91600..8ca737d 100644 (file)
@@ -184,7 +184,7 @@ Compiling ``pop∘swap∘roll<``
 
 The simplest way to “compile” this function would be something like:
 
-.. code:: ipython2
+.. code:: python
 
     def poswrd(s, e, d):
         return rolldown(*swap(*pop(s, e, d)))
@@ -200,7 +200,7 @@ Looking ahead for a moment, from the stack effect comment:
 
 We should be able to directly write out a Python function like:
 
-.. code:: ipython2
+.. code:: python
 
     def poswrd(stack):
         (_, (a, (b, (c, stack)))) = stack
@@ -393,7 +393,7 @@ And there you have it, the stack effect for
 From this stack effect comment it should be possible to construct the
 following Python code:
 
-.. code:: ipython2
+.. code:: python
 
     def F(stack):
         (_, (d, (c, ((a, (b, S0)), stack)))) = stack
@@ -408,7 +408,7 @@ Representing Stack Effect Comments in Python
 I’m going to use pairs of tuples of type descriptors, which will be
 integers or tuples of type descriptors:
 
-.. code:: ipython2
+.. code:: python
 
     roll_dn = (1, 2, 3), (2, 3, 1)
     
@@ -419,7 +419,7 @@ integers or tuples of type descriptors:
 ``compose()``
 ~~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     def compose(f, g):
     
@@ -465,7 +465,7 @@ integers or tuples of type descriptors:
 ``unify()``
 ~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     def unify(u, v, s=None):
         if s is None:
@@ -483,7 +483,7 @@ integers or tuples of type descriptors:
 ``update()``
 ~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     def update(s, term):
         if not isinstance(term, tuple):
@@ -493,7 +493,7 @@ integers or tuples of type descriptors:
 ``relabel()``
 ~~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     def relabel(left, right):
         return left, _1000(right)
@@ -517,7 +517,7 @@ integers or tuples of type descriptors:
 ``delabel()``
 ~~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     def delabel(f):
         s = {u: i for i, u in enumerate(sorted(_unique(f)))}
@@ -551,7 +551,7 @@ At last we put it all together in a function ``C()`` that accepts two
 stack effect comments and returns their composition (or raises and
 exception if they can’t be composed due to type conflicts.)
 
-.. code:: ipython2
+.. code:: python
 
     def C(f, g):
         f, g = relabel(f, g)
@@ -560,7 +560,7 @@ exception if they can’t be composed due to type conflicts.)
 
 Let’s try it out.
 
-.. code:: ipython2
+.. code:: python
 
     C(pop, swap)
 
@@ -573,7 +573,7 @@ Let’s try it out.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     C(C(pop, swap), roll_dn)
 
@@ -586,7 +586,7 @@ Let’s try it out.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     C(swap, roll_dn)
 
@@ -599,7 +599,7 @@ Let’s try it out.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     C(pop, C(swap, roll_dn))
 
@@ -612,7 +612,7 @@ Let’s try it out.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     poswrd = reduce(C, (pop, swap, roll_dn))
     poswrd
@@ -633,13 +633,13 @@ Here’s that trick to represent functions like ``rest`` and ``cons`` that
 manipulate stacks. We use a cons-list of tuples and give the tails their
 own numbers. Then everything above already works.
 
-.. code:: ipython2
+.. code:: python
 
     rest = ((1, 2),), (2,)
     
     cons = (1, 2), ((1, 2),)
 
-.. code:: ipython2
+.. code:: python
 
     C(poswrd, rest)
 
@@ -671,7 +671,7 @@ The translation table, if you will, would be:
    0: 0,
    }
 
-.. code:: ipython2
+.. code:: python
 
     F = reduce(C, (pop, swap, roll_dn, rest, rest, cons, cons))
     
@@ -699,11 +699,11 @@ Dealing with ``cons`` and ``uncons``
 However, if we try to compose e.g. ``cons`` and ``uncons`` it won’t
 work:
 
-.. code:: ipython2
+.. code:: python
 
     uncons = ((1, 2),), (1, 2)
 
-.. code:: ipython2
+.. code:: python
 
     try:
         C(cons, uncons)
@@ -723,7 +723,7 @@ The problem is that the ``unify()`` function as written doesn’t handle
 the case when both terms are tuples. We just have to add a clause to
 deal with this recursively:
 
-.. code:: ipython2
+.. code:: python
 
     def unify(u, v, s=None):
         if s is None:
@@ -753,7 +753,7 @@ deal with this recursively:
     
         return s
 
-.. code:: ipython2
+.. code:: python
 
     C(cons, uncons)
 
@@ -771,7 +771,7 @@ Part III: Compiling Yin Functions
 
 Now consider the Python function we would like to derive:
 
-.. code:: ipython2
+.. code:: python
 
     def F_python(stack):
         (_, (d, (c, ((a, (b, S0)), stack)))) = stack
@@ -779,7 +779,7 @@ Now consider the Python function we would like to derive:
 
 And compare it to the input stack effect comment tuple we just computed:
 
-.. code:: ipython2
+.. code:: python
 
     F[0]
 
@@ -816,7 +816,7 @@ Eh?
 
 And the return tuple
 
-.. code:: ipython2
+.. code:: python
 
     F[1]
 
@@ -848,7 +848,7 @@ Python Identifiers
 We want to substitute Python identifiers for the integers. I’m going to
 repurpose ``joy.parser.Symbol`` class for this:
 
-.. code:: ipython2
+.. code:: python
 
     from collections import defaultdict
     from joy.parser import Symbol
@@ -874,7 +874,7 @@ effect comment tuples to reasonable text format. There are some details
 in how this code works that related to stuff later in the notebook, so
 you should skip it for now and read it later if you’re interested.
 
-.. code:: ipython2
+.. code:: python
 
     def doc_from_stack_effect(inputs, outputs):
         return '(%s--%s)' % (
@@ -914,7 +914,7 @@ Now we can write a compiler function to emit Python source code. (The
 underscore suffix distiguishes it from the built-in ``compile()``
 function.)
 
-.. code:: ipython2
+.. code:: python
 
     def compile_(name, f, doc=None):
         if doc is None:
@@ -932,7 +932,7 @@ function.)
 
 Here it is in action:
 
-.. code:: ipython2
+.. code:: python
 
     source = compile_('F', F)
     
@@ -949,7 +949,7 @@ Here it is in action:
 
 Compare:
 
-.. code:: ipython2
+.. code:: python
 
     def F_python(stack):
         (_, (d, (c, ((a, (b, S0)), stack)))) = stack
@@ -957,7 +957,7 @@ Compare:
 
 Next steps:
 
-.. code:: ipython2
+.. code:: python
 
     L = {}
     
@@ -976,16 +976,16 @@ Next steps:
 
 Let’s try it out:
 
-.. code:: ipython2
+.. code:: python
 
     from notebook_preamble import D, J, V
     from joy.library import SimpleFunctionWrapper
 
-.. code:: ipython2
+.. code:: python
 
     D['F'] = SimpleFunctionWrapper(L['F'])
 
-.. code:: ipython2
+.. code:: python
 
     J('[4 5 ...] 2 3 1 F')
 
@@ -1012,7 +1012,7 @@ Compiling Library Functions
 We can use ``compile_()`` to generate many primitives in the library
 from their stack effect comments:
 
-.. code:: ipython2
+.. code:: python
 
     def defs():
     
@@ -1036,7 +1036,7 @@ from their stack effect comments:
     
         return locals()
 
-.. code:: ipython2
+.. code:: python
 
     for name, stack_effect_comment in sorted(defs().items()):
         print
@@ -1205,7 +1205,7 @@ Python class hierarchy of Joy types and use the ``issubclass()`` method
 to establish domain ordering, as well as other handy behaviour that will
 make it fairly easy to reuse most of the code above.
 
-.. code:: ipython2
+.. code:: python
 
     class AnyJoyType(object):
     
@@ -1251,14 +1251,14 @@ make it fairly easy to reuse most of the code above.
 
 Mess with it a little:
 
-.. code:: ipython2
+.. code:: python
 
     from itertools import permutations
 
 “Any” types can be specialized to numbers and stacks, but not vice
 versa:
 
-.. code:: ipython2
+.. code:: python
 
     for a, b in permutations((A[0], N[0], S[0]), 2):
         print a, '>=', b, '->', a >= b
@@ -1278,7 +1278,7 @@ Our crude `Numerical
 Tower <https://en.wikipedia.org/wiki/Numerical_tower>`__ of *numbers* >
 *floats* > *integers* works as well (but we’re not going to use it yet):
 
-.. code:: ipython2
+.. code:: python
 
     for a, b in permutations((A[0], N[0], FloatJoyType(0), IntJoyType(0)), 2):
         print a, '>=', b, '->', a >= b
@@ -1303,13 +1303,13 @@ Tower <https://en.wikipedia.org/wiki/Numerical_tower>`__ of *numbers* >
 Typing ``sqr``
 ~~~~~~~~~~~~~~
 
-.. code:: ipython2
+.. code:: python
 
     dup = (A[1],), (A[1], A[1])
     
     mul = (N[1], N[2]), (N[3],)
 
-.. code:: ipython2
+.. code:: python
 
     dup
 
@@ -1322,7 +1322,7 @@ Typing ``sqr``
 
 
 
-.. code:: ipython2
+.. code:: python
 
     mul
 
@@ -1340,7 +1340,7 @@ Modifying the Inferencer
 
 Re-labeling still works fine:
 
-.. code:: ipython2
+.. code:: python
 
     foo = relabel(dup, mul)
     
@@ -1361,7 +1361,7 @@ Re-labeling still works fine:
 The ``delabel()`` function needs an overhaul. It now has to keep track
 of how many labels of each domain it has “seen”.
 
-.. code:: ipython2
+.. code:: python
 
     from collections import Counter
     
@@ -1383,7 +1383,7 @@ of how many labels of each domain it has “seen”.
     
         return tuple(delabel(inner, seen, c) for inner in f)
 
-.. code:: ipython2
+.. code:: python
 
     delabel(foo)
 
@@ -1399,7 +1399,7 @@ of how many labels of each domain it has “seen”.
 ``unify()`` version 3
 ^^^^^^^^^^^^^^^^^^^^^
 
-.. code:: ipython2
+.. code:: python
 
     def unify(u, v, s=None):
         if s is None:
@@ -1449,7 +1449,7 @@ of how many labels of each domain it has “seen”.
 
 Rewrite the stack effect comments:
 
-.. code:: ipython2
+.. code:: python
 
     def defs():
     
@@ -1503,11 +1503,11 @@ Rewrite the stack effect comments:
     
         return locals()
 
-.. code:: ipython2
+.. code:: python
 
     DEFS = defs()
 
-.. code:: ipython2
+.. code:: python
 
     for name, stack_effect_comment in sorted(DEFS.items()):
         print name, '=', doc_from_stack_effect(*stack_effect_comment)
@@ -1543,14 +1543,14 @@ Rewrite the stack effect comments:
     uncons = ([a1 .1.] -- a1 [.1.])
 
 
-.. code:: ipython2
+.. code:: python
 
     globals().update(DEFS)
 
 Compose ``dup`` and ``mul``
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. code:: ipython2
+.. code:: python
 
     C(dup, mul)
 
@@ -1565,7 +1565,7 @@ Compose ``dup`` and ``mul``
 
 Revisit the ``F`` function, works fine.
 
-.. code:: ipython2
+.. code:: python
 
     F = reduce(C, (pop, swap, rolldown, rest, rest, cons, cons))
     F
@@ -1579,7 +1579,7 @@ Revisit the ``F`` function, works fine.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     print doc_from_stack_effect(*F)
 
@@ -1592,12 +1592,12 @@ Revisit the ``F`` function, works fine.
 Some otherwise inefficient functions are no longer to be feared. We can
 also get the effect of combinators in some limited cases.
 
-.. code:: ipython2
+.. code:: python
 
     def neato(*funcs):
         print doc_from_stack_effect(*reduce(C, funcs))
 
-.. code:: ipython2
+.. code:: python
 
     # e.g. [swap] dip
     neato(rollup, swap, rolldown)
@@ -1608,7 +1608,7 @@ also get the effect of combinators in some limited cases.
     (a1 a2 a3 -- a2 a1 a3)
 
 
-.. code:: ipython2
+.. code:: python
 
     # e.g. [popop] dipd
     neato(popdd, rolldown, pop)
@@ -1619,7 +1619,7 @@ also get the effect of combinators in some limited cases.
     (a1 a2 a3 a4 -- a3 a4)
 
 
-.. code:: ipython2
+.. code:: python
 
     # Reverse the order of the top three items.
     neato(rollup, swap)
@@ -1636,7 +1636,7 @@ also get the effect of combinators in some limited cases.
 Because the type labels represent themselves as valid Python identifiers
 the ``compile_()`` function doesn’t need to generate them anymore:
 
-.. code:: ipython2
+.. code:: python
 
     def compile_(name, f, doc=None):
         inputs, outputs = f
@@ -1652,7 +1652,7 @@ the ``compile_()`` function doesn’t need to generate them anymore:
         %s = stack
         return %s''' % (name, doc, i, o)
 
-.. code:: ipython2
+.. code:: python
 
     print compile_('F', F)
 
@@ -1668,7 +1668,7 @@ the ``compile_()`` function doesn’t need to generate them anymore:
 But it cannot magically create new functions that involve e.g. math and
 such. Note that this is *not* a ``sqr`` function implementation:
 
-.. code:: ipython2
+.. code:: python
 
     print compile_('sqr', C(dup, mul))
 
@@ -1696,7 +1696,7 @@ 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:
 
-.. code:: ipython2
+.. code:: python
 
     from itertools import imap
     
@@ -1704,7 +1704,7 @@ comments. We can write a function to check that:
     def compilable(f):
         return isinstance(f, tuple) and all(imap(compilable, f)) or stacky(f)
 
-.. code:: ipython2
+.. code:: python
 
     for name, stack_effect_comment in sorted(defs().items()):
         if compilable(stack_effect_comment):
@@ -1828,7 +1828,7 @@ the “truthiness” of ``StackJoyType`` to false to let e.g.
 ``joy.utils.stack.concat`` work with our stack effect comment cons-list
 tuples.)
 
-.. code:: ipython2
+.. code:: python
 
     def compose(f, g):
         (f_in, f_out), (g_in, g_out) = f, g
@@ -1840,7 +1840,7 @@ tuples.)
 I don’t want to rewrite all the defs myself, so I’ll write a little
 conversion function instead. This is programmer’s laziness.
 
-.. code:: ipython2
+.. code:: python
 
     def sequence_to_stack(seq, stack=StackJoyType(23)):
         for item in seq: stack = item, stack
@@ -1854,7 +1854,7 @@ conversion function instead. This is programmer’s laziness.
     NEW_DEFS['swaack'] = (S[1], S[0]), (S[0], S[1])
     globals().update(NEW_DEFS)
 
-.. code:: ipython2
+.. code:: python
 
     C(stack, uncons)
 
@@ -1867,7 +1867,7 @@ conversion function instead. This is programmer’s laziness.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     reduce(C, (stack, uncons, uncons))
 
@@ -1887,7 +1887,7 @@ The display function should be changed too.
 
 Clunky junk, but it will suffice for now.
 
-.. code:: ipython2
+.. code:: python
 
     def doc_from_stack_effect(inputs, outputs):
         switch = [False]  # Do we need to display the '...' for the rest of the main stack?
@@ -1935,7 +1935,7 @@ Clunky junk, but it will suffice for now.
         a.append(end)
         return '[%s]' % ' '.join(a)
 
-.. code:: ipython2
+.. code:: python
 
     for name, stack_effect_comment in sorted(NEW_DEFS.items()):
         print name, '=', doc_from_stack_effect(*stack_effect_comment)
@@ -1973,7 +1973,7 @@ Clunky junk, but it will suffice for now.
     uncons = ([a1 .1.] -- a1 [.1.])
 
 
-.. code:: ipython2
+.. code:: python
 
     print ; print doc_from_stack_effect(*stack)
     print ; print doc_from_stack_effect(*C(stack, uncons))
@@ -1993,7 +1993,7 @@ Clunky junk, but it will suffice for now.
     (... a1 -- ... a1 [a1 ...])
 
 
-.. code:: ipython2
+.. code:: python
 
     print doc_from_stack_effect(*C(ccons, stack))
 
@@ -2003,7 +2003,7 @@ Clunky junk, but it will suffice for now.
     (... a2 a1 [.1.] -- ... [a2 a1 .1.] [[a2 a1 .1.] ...])
 
 
-.. code:: ipython2
+.. code:: python
 
     Q = C(ccons, stack)
     
@@ -2024,7 +2024,7 @@ Clunky junk, but it will suffice for now.
 This makes the ``compile_()`` function pretty simple as the stack effect
 comments are now already in the form needed for the Python code:
 
-.. code:: ipython2
+.. code:: python
 
     def compile_(name, f, doc=None):
         i, o = f
@@ -2035,7 +2035,7 @@ comments are now already in the form needed for the Python code:
         %s = stack
         return %s''' % (name, doc, i, o)
 
-.. code:: ipython2
+.. code:: python
 
     print compile_('Q', Q)
 
@@ -2053,12 +2053,12 @@ comments are now already in the form needed for the Python code:
 
 
 
-.. code:: ipython2
+.. code:: python
 
     unstack = (S[1], S[0]), S[1]
     enstacken = S[0], (S[0], S[1])
 
-.. code:: ipython2
+.. code:: python
 
     print doc_from_stack_effect(*unstack)
 
@@ -2068,7 +2068,7 @@ comments are now already in the form needed for the Python code:
     ([.1.] --)
 
 
-.. code:: ipython2
+.. code:: python
 
     print doc_from_stack_effect(*enstacken)
 
@@ -2078,7 +2078,7 @@ comments are now already in the form needed for the Python code:
     (-- [.0.])
 
 
-.. code:: ipython2
+.. code:: python
 
     print doc_from_stack_effect(*C(cons, unstack))
 
@@ -2088,7 +2088,7 @@ comments are now already in the form needed for the Python code:
     (a1 [.1.] -- a1)
 
 
-.. code:: ipython2
+.. code:: python
 
     print doc_from_stack_effect(*C(cons, enstacken))
 
@@ -2098,7 +2098,7 @@ comments are now already in the form needed for the Python code:
     (a1 [.1.] -- [[a1 .1.] .2.])
 
 
-.. code:: ipython2
+.. code:: python
 
     C(cons, unstack)
 
@@ -2117,7 +2117,7 @@ Part VI: Multiple Stack Effects
 
 …
 
-.. code:: ipython2
+.. code:: python
 
     class IntJoyType(NumberJoyType): prefix = 'i'
     
@@ -2125,7 +2125,7 @@ Part VI: Multiple Stack Effects
     F = map(FloatJoyType, _R)
     I = map(IntJoyType, _R)
 
-.. code:: ipython2
+.. code:: python
 
     muls = [
          ((I[2], (I[1], S[0])), (I[3], S[0])),
@@ -2134,7 +2134,7 @@ Part VI: Multiple Stack Effects
          ((F[2], (F[1], S[0])), (F[3], S[0])),
     ]
 
-.. code:: ipython2
+.. code:: python
 
     for f in muls:
         print doc_from_stack_effect(*f)
@@ -2148,7 +2148,7 @@ Part VI: Multiple Stack Effects
     (f1 f2 -- f3)
 
 
-.. code:: ipython2
+.. code:: python
 
     for f in muls:
         try:
@@ -2164,7 +2164,7 @@ Part VI: Multiple Stack Effects
     (a1 -- a1 a1) (f1 f2 -- f3) (f1 -- f2)
 
 
-.. code:: ipython2
+.. code:: python
 
     from itertools import product
     
@@ -2180,7 +2180,7 @@ Part VI: Multiple Stack Effects
     def MC(F, G):
         return sorted(set(meta_compose(F, G)))
 
-.. code:: ipython2
+.. code:: python
 
     for f in MC([dup], [mul]):
         print doc_from_stack_effect(*f)
@@ -2191,7 +2191,7 @@ Part VI: Multiple Stack Effects
     (n1 -- n2)
 
 
-.. code:: ipython2
+.. code:: python
 
     for f in MC([dup], muls):
         print doc_from_stack_effect(*f)
@@ -2264,7 +2264,7 @@ Giving us two unifiers:
    {c: a,  d: b,  .1.:      .0.}
    {c: a,  d: e,  .1.: A* b .0.}
 
-.. code:: ipython2
+.. code:: python
 
     class KleeneStar(object):
     
@@ -2314,7 +2314,7 @@ Giving us two unifiers:
 
 Can now return multiple results…
 
-.. code:: ipython2
+.. code:: python
 
     def unify(u, v, s=None):
         if s is None:
@@ -2386,7 +2386,7 @@ Can now return multiple results…
     def stacky(thing):
         return thing.__class__ in {AnyJoyType, StackJoyType}
 
-.. code:: ipython2
+.. code:: python
 
     a = (As[1], S[1])
     a
@@ -2400,7 +2400,7 @@ Can now return multiple results…
 
 
 
-.. code:: ipython2
+.. code:: python
 
     b = (A[1], S[2])
     b
@@ -2414,7 +2414,7 @@ Can now return multiple results…
 
 
 
-.. code:: ipython2
+.. code:: python
 
     for result in unify(b, a):
         print result, '->', update(result, a), update(result, b)
@@ -2426,7 +2426,7 @@ Can now return multiple results…
     {a1: a10001, s2: (a1*, s1)} -> (a1*, s1) (a10001, (a1*, s1))
 
 
-.. code:: ipython2
+.. code:: python
 
     for result in unify(a, b):
         print result, '->', update(result, a), update(result, b)
@@ -2446,7 +2446,7 @@ Can now return multiple results…
 
    (a1*, s1)       [a1*]       (a2, (a1*, s1)) [a2 a1*]
 
-.. code:: ipython2
+.. code:: python
 
     sum_ = ((Ns[1], S[1]), S[0]), (N[0], S[0])
     
@@ -2458,7 +2458,7 @@ Can now return multiple results…
     ([n1* .1.] -- n0)
 
 
-.. code:: ipython2
+.. code:: python
 
     f = (N[1], (N[2], (N[3], S[1]))), S[0]
     
@@ -2470,7 +2470,7 @@ Can now return multiple results…
     (-- [n1 n2 n3 .1.])
 
 
-.. code:: ipython2
+.. code:: python
 
     for result in unify(sum_[0], f):
         print result, '->', update(result, sum_[1])
@@ -2489,7 +2489,7 @@ Can now return multiple results…
 
 This function has to be modified to yield multiple results.
 
-.. code:: ipython2
+.. code:: python
 
     def compose(f, g):
         (f_in, f_out), (g_in, g_out) = f, g
@@ -2501,7 +2501,7 @@ This function has to be modified to yield multiple results.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     def meta_compose(F, G):
         for f, g in product(F, G):
@@ -2517,7 +2517,7 @@ This function has to be modified to yield multiple results.
         for fg in compose(f, g):
             yield delabel(fg)
 
-.. code:: ipython2
+.. code:: python
 
     for f in MC([dup], muls):
         print doc_from_stack_effect(*f)
@@ -2529,7 +2529,7 @@ This function has to be modified to yield multiple results.
     (i1 -- i2)
 
 
-.. code:: ipython2
+.. code:: python
 
     
     
@@ -2542,7 +2542,7 @@ This function has to be modified to yield multiple results.
     ([n1* .1.] -- [n1* .1.] n1)
 
 
-.. code:: ipython2
+.. code:: python
 
     
     
@@ -2556,7 +2556,7 @@ This function has to be modified to yield multiple results.
     (n1 [n1* .1.] -- n2)
 
 
-.. code:: ipython2
+.. code:: python
 
     sum_ = (((N[1], (Ns[1], S[1])), S[0]), (N[0], S[0]))
     print doc_from_stack_effect(*cons),
@@ -2571,7 +2571,7 @@ This function has to be modified to yield multiple results.
     (a1 [.1.] -- [a1 .1.]) ([n1 n1* .1.] -- n0) (n1 [n1* .1.] -- n2)
 
 
-.. code:: ipython2
+.. code:: python
 
     a = (A[4], (As[1], (A[3], S[1])))
     a
@@ -2585,7 +2585,7 @@ This function has to be modified to yield multiple results.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     b = (A[1], (A[2], S[2]))
     b
@@ -2599,7 +2599,7 @@ This function has to be modified to yield multiple results.
 
 
 
-.. code:: ipython2
+.. code:: python
 
     for result in unify(b, a):
         print result
@@ -2611,7 +2611,7 @@ This function has to be modified to yield multiple results.
     {a1: a4, s2: (a1*, (a3, s1)), a2: a10003}
 
 
-.. code:: ipython2
+.. code:: python
 
     for result in unify(a, b):
         print result
@@ -2681,7 +2681,7 @@ We need a type variable for Joy functions that can go in our expressions
 and be used by the hybrid inferencer/interpreter. They have to store a
 name and a list of stack effects.
 
-.. code:: ipython2
+.. code:: python
 
     class FunctionJoyType(AnyJoyType):
     
@@ -2703,14 +2703,14 @@ Specialized for Simple Functions and Combinators
 For non-combinator functions the stack effects list contains stack
 effect comments (represented by pairs of cons-lists as described above.)
 
-.. code:: ipython2
+.. code:: python
 
     class SymbolJoyType(FunctionJoyType):
         prefix = 'F'
 
 For combinators the list contains Python functions.
 
-.. code:: ipython2
+.. code:: python
 
     class CombinatorJoyType(FunctionJoyType):
     
@@ -2731,7 +2731,7 @@ For combinators the list contains Python functions.
 For simple combinators that have only one effect (like ``dip``) you only
 need one function and it can be the combinator itself.
 
-.. code:: ipython2
+.. code:: python
 
     import joy.library
     
@@ -2741,7 +2741,7 @@ For combinators that can have more than one effect (like ``branch``) you
 have to write functions that each implement the action of one of the
 effects.
 
-.. code:: ipython2
+.. code:: python
 
     def branch_true(stack, expression, dictionary):
         (then, (else_, (flag, stack))) = stack
@@ -2771,7 +2771,7 @@ updated along with the stack effects after doing unification or we risk
 losing useful information. This was a straightforward, if awkward,
 modification to the call structure of ``meta_compose()`` et. al.
 
-.. code:: ipython2
+.. code:: python
 
     ID = S[0], S[0]  # Identity function.
     
@@ -2833,7 +2833,7 @@ cruft to convert the definitions in ``DEFS`` to the new
 ``SymbolJoyType`` objects, and some combinators. Here is an example of
 output from the current code :
 
-.. code:: ipython2
+.. code:: python
 
     1/0  # (Don't try to run this cell!  It's not going to work.  This is "read only" code heh..)
     
@@ -2956,7 +2956,7 @@ module. But if you’re interested in all that you should just use Prolog!
 
 Anyhow, type *checking* is a few easy steps away.
 
-.. code:: ipython2
+.. code:: python
 
     def _ge(self, other):
         return (issubclass(other.__class__, self.__class__)
index dc4f996..c44343a 100644 (file)
@@ -10,7 +10,7 @@ Huet <https://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-
 Given a datastructure on the stack we can navigate through it, modify
 it, and rebuild it using the “zipper” technique.
 
-.. code:: ipython2
+.. code:: python
 
     from notebook_preamble import J, V, define
 
@@ -23,7 +23,7 @@ strings, Symbols (strings that are names of functions) and sequences
 `trees <https://en.wikipedia.org/wiki/Tree_%28data_structure%29>`__ out
 of sequences.
 
-.. code:: ipython2
+.. code:: python
 
     J('[1 [2 [3 4 25 6] 7] 8]')
 
@@ -54,14 +54,14 @@ show the trace so you can see how it works. If we were going to use
 these a lot it would make sense to write Python versions for efficiency,
 but see below.
 
-.. code:: ipython2
+.. code:: python
 
     define('z-down == [] swap uncons swap')
     define('z-up == swons swap shunt')
     define('z-right == [swons] cons dip uncons swap')
     define('z-left == swons [uncons swap] dip swap')
 
-.. code:: ipython2
+.. code:: python
 
     V('[1 [2 [3 4 25 6] 7] 8] z-down')
 
@@ -77,7 +77,7 @@ but see below.
     [] [[2 [3 4 25 6] 7] 8] 1 . 
 
 
-.. code:: ipython2
+.. code:: python
 
     V('[] [[2 [3 4 25 6] 7] 8] 1 z-right')
 
@@ -101,7 +101,7 @@ but see below.
              [1] [8] [2 [3 4 25 6] 7] . 
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[1] [8] [2 [3 4 25 6] 7] z-down')
 
@@ -111,7 +111,7 @@ but see below.
     [1] [8] [] [[3 4 25 6] 7] 2
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[1] [8] [] [[3 4 25 6] 7] 2 z-right')
 
@@ -121,7 +121,7 @@ but see below.
     [1] [8] [2] [7] [3 4 25 6]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[1] [8] [2] [7] [3 4 25 6] z-down')
 
@@ -131,7 +131,7 @@ but see below.
     [1] [8] [2] [7] [] [4 25 6] 3
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[1] [8] [2] [7] [] [4 25 6] 3 z-right')
 
@@ -141,7 +141,7 @@ but see below.
     [1] [8] [2] [7] [3] [25 6] 4
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[1] [8] [2] [7] [3] [25 6] 4 z-right')
 
@@ -151,7 +151,7 @@ but see below.
     [1] [8] [2] [7] [4 3] [6] 25
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[1] [8] [2] [7] [4 3] [6] 25 sqr')
 
@@ -161,7 +161,7 @@ but see below.
     [1] [8] [2] [7] [4 3] [6] 625
 
 
-.. code:: ipython2
+.. code:: python
 
     V('[1] [8] [2] [7] [4 3] [6] 625 z-up')
 
@@ -184,7 +184,7 @@ but see below.
       [1] [8] [2] [7] [3 4 625 6] . 
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[1] [8] [2] [7] [3 4 625 6] z-up')
 
@@ -194,7 +194,7 @@ but see below.
     [1] [8] [2 [3 4 625 6] 7]
 
 
-.. code:: ipython2
+.. code:: python
 
     J('[1] [8] [2 [3 4 625 6] 7] z-up')
 
@@ -210,7 +210,7 @@ but see below.
 In Joy we have the ``dip`` and ``infra`` combinators which can “target”
 or “address” any particular item in a Joy tree structure.
 
-.. code:: ipython2
+.. code:: python
 
     V('[1 [2 [3 4 25 6] 7] 8] [[[[[[sqr] dipd] infra] dip] infra] dip] infra')
 
@@ -270,13 +270,13 @@ been embedded in a nested series of quoted programs, e.g.:
 
 The ``Z`` function isn’t hard to make.
 
-.. code:: ipython2
+.. code:: python
 
     define('Z == [[] cons cons] step i')
 
 Here it is in action in a simplified scenario.
 
-.. code:: ipython2
+.. code:: python
 
     V('1 [2 3 4] Z')
 
@@ -314,7 +314,7 @@ Here it is in action in a simplified scenario.
 
 And here it is doing the main thing.
 
-.. code:: ipython2
+.. code:: python
 
     J('[1 [2 [3 4 25 6] 7] 8] [sqr] [dip dip infra dip infra dip infra] Z')