+
-
+
+
+
+
diff --git a/docs/Square_Spiral.ipynb b/docs/Square_Spiral.ipynb
index 8dc4273..96ea19b 100644
--- a/docs/Square_Spiral.ipynb
+++ b/docs/Square_Spiral.ipynb
@@ -1,14 +1,5 @@
{
"cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "from notebook_preamble import J, V, define"
- ]
- },
{
"cell_type": "markdown",
"metadata": {},
@@ -93,7 +84,87 @@
"apply `abs` to both values and then compare them\n",
"with `<=`:\n",
"\n",
- " [abs] ii <=\n",
+ " [abs] ii <="
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
+ "source": [
+ "[_p [abs] ii <=] inscribe"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "23 -18"
+ ]
+ }
+ ],
+ "source": [
+ "clear 23 -18"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " 23 -18 • _p\n",
+ " 23 -18 • [abs] ii <=\n",
+ "23 -18 [abs] • ii <=\n",
+ " 23 • abs -18 abs <=\n",
+ " 23 • -18 abs <=\n",
+ " 23 -18 • abs <=\n",
+ " 23 18 • <=\n",
+ " false • \n",
+ "\n",
+ "false"
+ ]
+ }
+ ],
+ "source": [
+ "[_p] trace"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
+ "source": [
+ "clear"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Short-Circuiting Boolean Combinators\n",
"\n",
"I've defined two short-circuiting Boolean combinators `&&` and `||` that\n",
"each accept two quoted predicate programs, run the first, and\n",
@@ -103,30 +174,246 @@
},
{
"cell_type": "code",
- "execution_count": 2,
+ "execution_count": 5,
"metadata": {},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
"source": [
- "define('&& [nullary] cons [nullary [0]] dip branch')\n",
- "define('|| [nullary] cons [nullary] dip [1] branch')"
+ "[&& [nullary] cons [nullary [false]] dip branch] inscribe\n",
+ "[|| [nullary] cons [nullary] dip [true] branch] inscribe"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "false"
+ ]
+ }
+ ],
+ "source": [
+ "clear \n",
+ "[true] [false] &&"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "false"
+ ]
+ }
+ ],
+ "source": [
+ "clear \n",
+ "[false] [true] &&"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "true"
+ ]
+ }
+ ],
+ "source": [
+ "clear \n",
+ "[true] [false] ||"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "true"
+ ]
+ }
+ ],
+ "source": [
+ "clear \n",
+ "[false] [true] ||"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
+ "source": [
+ "clear"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
+ "### Translating the Conditionals\n",
+ "\n",
"Given those, we can define `x != y || x >= 0` as:\n",
"\n",
- " [<>] [pop 0 >=] ||\n",
- "\n",
+ " _a == [!=] [pop 0 >=] ||"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
+ "source": [
+ "[_a [!=] [pop 0 >=] ||] inscribe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
"And `(abs(x) <= abs(y) && (x != y || x >= 0))` as:\n",
"\n",
- " [[abs] ii <=] [[<>] [pop 0 >=] ||] &&\n",
- "\n",
+ " _b == [_p] [_a] &&"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
+ "source": [
+ "[_b [_p] [_a] &&] inscribe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
"It's a little rough, but, as I say, with a little familiarity it becomes\n",
"legible."
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "23 -18"
+ ]
+ }
+ ],
+ "source": [
+ "clear 23 -18"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " 23 -18 • _b\n",
+ " 23 -18 • [_p] [_a] &&\n",
+ " 23 -18 [_p] • [_a] &&\n",
+ " 23 -18 [_p] [_a] • &&\n",
+ " 23 -18 [_p] [_a] • [nullary] cons [nullary [false]] dip branch\n",
+ " 23 -18 [_p] [_a] [nullary] • cons [nullary [false]] dip branch\n",
+ " 23 -18 [_p] [[_a] nullary] • [nullary [false]] dip branch\n",
+ "23 -18 [_p] [[_a] nullary] [nullary [false]] • dip branch\n",
+ " 23 -18 [_p] • nullary [false] [[_a] nullary] branch\n",
+ " 23 -18 [_p] • [stack] dinfrirst [false] [[_a] nullary] branch\n",
+ " 23 -18 [_p] [stack] • dinfrirst [false] [[_a] nullary] branch\n",
+ " 23 -18 [_p] [stack] • dip infrst [false] [[_a] nullary] branch\n",
+ " 23 -18 • stack [_p] infrst [false] [[_a] nullary] branch\n",
+ " 23 -18 [-18 23] • [_p] infrst [false] [[_a] nullary] branch\n",
+ " 23 -18 [-18 23] [_p] • infrst [false] [[_a] nullary] branch\n",
+ " 23 -18 [-18 23] [_p] • infra first [false] [[_a] nullary] branch\n",
+ " 23 -18 • _p [-18 23] swaack first [false] [[_a] nullary] branch\n",
+ " 23 -18 • [abs] ii <= [-18 23] swaack first [false] [[_a] nullary] branch\n",
+ " 23 -18 [abs] • ii <= [-18 23] swaack first [false] [[_a] nullary] branch\n",
+ " 23 • abs -18 abs <= [-18 23] swaack first [false] [[_a] nullary] branch\n",
+ " 23 • -18 abs <= [-18 23] swaack first [false] [[_a] nullary] branch\n",
+ " 23 -18 • abs <= [-18 23] swaack first [false] [[_a] nullary] branch\n",
+ " 23 18 • <= [-18 23] swaack first [false] [[_a] nullary] branch\n",
+ " false • [-18 23] swaack first [false] [[_a] nullary] branch\n",
+ " false [-18 23] • swaack first [false] [[_a] nullary] branch\n",
+ " 23 -18 [false] • first [false] [[_a] nullary] branch\n",
+ " 23 -18 false • [false] [[_a] nullary] branch\n",
+ " 23 -18 false [false] • [[_a] nullary] branch\n",
+ " 23 -18 false [false] [[_a] nullary] • branch\n",
+ " 23 -18 • false\n",
+ " 23 -18 false • \n",
+ "\n",
+ "23 -18 false"
+ ]
+ }
+ ],
+ "source": [
+ "[_b] trace"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
+ "source": [
+ "clear"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -158,22 +445,6 @@
" [pop 0 >=] [--] [++] ifte"
]
},
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### \"Not Negative\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [],
- "source": [
- "define('!- 0 >=')"
- ]
- },
{
"cell_type": "markdown",
"metadata": {},
@@ -187,8 +458,35 @@
" [[[abs] ii <=] [[<>] [pop !-] ||] &&]\n",
" [[ !-] [[++]] [[--]] ifte dip]\n",
" [[pop !-] [--] [++] ifte ]\n",
- " ifte\n",
+ " ifte"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
+ "source": [
+ "[spiral_next\n",
"\n",
+ "[_b]\n",
+ "[[ !-] [[++]] [[--]] ifte dip]\n",
+ "[[pop !-] [--] [++] ifte ]\n",
+ "ifte\n",
+ "\n",
+ "] inscribe"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
"As I was writing this up I realized that, since the `&&` combinator\n",
"doesn't consume the stack (below its quoted args), I can unquote the\n",
"predicate, swap the branches, and use the `branch` combinator instead of\n",
@@ -200,15 +498,6 @@
" branch"
]
},
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [],
- "source": [
- "define('spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte')"
- ]
- },
{
"cell_type": "markdown",
"metadata": {},
@@ -218,70 +507,274 @@
},
{
"cell_type": "code",
- "execution_count": 5,
+ "execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "1 0\n"
+ "0 0"
]
}
],
"source": [
- "J('0 0 spiral_next')"
+ "clear 0 0"
]
},
{
"cell_type": "code",
- "execution_count": 6,
+ "execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "1 -1\n"
+ "1 0"
]
}
],
"source": [
- "J('1 0 spiral_next')"
+ "spiral_next"
]
},
{
"cell_type": "code",
- "execution_count": 7,
+ "execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "0 -1\n"
+ "1 -1"
]
}
],
"source": [
- "J('1 -1 spiral_next')"
+ "spiral_next"
]
},
{
"cell_type": "code",
- "execution_count": 8,
+ "execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "-1 -1\n"
+ "0 -1"
]
}
],
"source": [
- "J('0 -1 spiral_next')"
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "-1 -1"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "-1 0"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "-1 1"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0 1"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 1"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2 1"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2 0"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2 -1"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2 -2"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1 -2"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0 -2"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 32,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "-1 -2"
+ ]
+ }
+ ],
+ "source": [
+ "spiral_next"
]
},
{
@@ -296,27 +789,63 @@
"\n",
"We can use `codireco` to make a generator\n",
"\n",
- " codireco ::= cons dip rest cons\n",
+ " codireco == cons dip rest cons\n",
"\n",
"It will look like this:\n",
"\n",
" [value [F] codireco]\n",
"\n",
- "Here's a trace of how it works:\n",
+ "Here's a trace of how it works:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " [0 [dup ++] codireco] • x\n",
+ " [0 [dup ++] codireco] • 0 [dup ++] codireco\n",
+ " [0 [dup ++] codireco] 0 • [dup ++] codireco\n",
+ "[0 [dup ++] codireco] 0 [dup ++] • codireco\n",
+ "[0 [dup ++] codireco] 0 [dup ++] • codi reco\n",
+ "[0 [dup ++] codireco] 0 [dup ++] • cons dip reco\n",
+ "[0 [dup ++] codireco] [0 dup ++] • dip reco\n",
+ " • 0 dup ++ [0 [dup ++] codireco] reco\n",
+ " 0 • dup ++ [0 [dup ++] codireco] reco\n",
+ " 0 0 • ++ [0 [dup ++] codireco] reco\n",
+ " 0 1 • [0 [dup ++] codireco] reco\n",
+ " 0 1 [0 [dup ++] codireco] • reco\n",
+ " 0 1 [0 [dup ++] codireco] • rest cons\n",
+ " 0 1 [[dup ++] codireco] • cons\n",
+ " 0 [1 [dup ++] codireco] • \n",
+ "\n",
+ "0 [1 [dup ++] codireco]"
+ ]
+ }
+ ],
+ "source": [
+ "clear\n",
"\n",
- " [0 [dup ++] codireco] . x\n",
- " [0 [dup ++] codireco] . 0 [dup ++] codireco\n",
- " [0 [dup ++] codireco] 0 . [dup ++] codireco\n",
- " [0 [dup ++] codireco] 0 [dup ++] . codireco\n",
- " [0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons\n",
- " [0 [dup ++] codireco] [0 dup ++] . dip rest cons\n",
- " . 0 dup ++ [0 [dup ++] codireco] rest cons\n",
- " 0 . dup ++ [0 [dup ++] codireco] rest cons\n",
- " 0 0 . ++ [0 [dup ++] codireco] rest cons\n",
- " 0 1 . [0 [dup ++] codireco] rest cons\n",
- " 0 1 [0 [dup ++] codireco] . rest cons\n",
- " 0 1 [[dup ++] codireco] . cons\n",
- " 0 [1 [dup ++] codireco] . "
+ "[0 [dup ++] codireco] [x] trace"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
+ "source": [
+ "clear"
]
},
{
@@ -340,19 +869,19 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "[0 1]\n"
+ "[0 1]"
]
}
],
"source": [
- "J('[0 0] [spiral_next] infra')"
+ "[0 0] [spiral_next] infra"
]
},
{
@@ -375,6 +904,21 @@
" [[0 0] [dup [spiral_next] infra] codireco]"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": []
+ }
+ ],
+ "source": [
+ "clear"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -384,26 +928,47 @@
},
{
"cell_type": "code",
- "execution_count": 10,
+ "execution_count": 37,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
- "[0 0] [0 1] [-1 1] [-1 0]\n"
+ "[0 0] [0 1] [-1 1] [-1 0]"
]
}
],
"source": [
- "J('[0 0] [dup [spiral_next] infra] make_generator x x x x pop')"
+ "[0 0] [dup [spiral_next] infra] make_generator x x x x pop"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "Four `x` combinators, four pairs of coordinates."
+ "Four `x` combinators, four pairs of coordinates.\n",
+ "\n",
+ "Or you can leave out `dup` and let the value stay in the generator until you want it:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[2 4]"
+ ]
+ }
+ ],
+ "source": [
+ "clear\n",
+ "\n",
+ "[0 0] [[spiral_next] infra] make_generator 50 [x] times first"
]
},
{
@@ -416,12 +981,14 @@
"the original. It's a little long for a single definition, you might\n",
"break it up like so:\n",
"\n",
- " _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&\n",
+ " _spn_Pa == [abs] ii <=\n",
+ " _spn_Pb == [!=] [pop 0 >=] ||\n",
+ " _spn_P == [_spn_Pa] [_spn_Pb] &&\n",
+ " \n",
+ " _spn_T == [ !-] [[++]] [[--]] ifte dip\n",
+ " _spn_E == [pop !-] [--] [++] ifte\n",
"\n",
- " _spn_T ::= [ !-] [[++]] [[--]] ifte dip\n",
- " _spn_E ::= [pop !-] [--] [++] ifte\n",
- "\n",
- " spiral_next ::= _spn_P [_spn_E] [_spn_T] branch\n",
+ " spiral_next == _spn_P [_spn_E] [_spn_T] branch\n",
"\n",
"This way it's easy to see that the function is a branch with two\n",
"quasi-symmetrical paths.\n",
@@ -432,121 +999,18 @@
"expression containing a copy of the current pair and the \"stepper\n",
"function\" to generate the next pair from that.)"
]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "metadata": {},
- "outputs": [],
- "source": [
- "define('_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&')\n",
- "define('_spn_T [!-] [[++]] [[--]] ifte dip')\n",
- "define('_spn_E [pop !-] [--] [++] ifte')\n",
- "define('spiral_next _spn_P [_spn_E] [_spn_T] branch')"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {
- "scrolled": true
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- " . 23 18 spiral_next\n",
- " 23 . 18 spiral_next\n",
- " 23 18 . spiral_next\n",
- " 23 18 . _spn_P [_spn_E] [_spn_T] branch\n",
- " 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch\n",
- " 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch\n",
- " 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch\n",
- " 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch\n",
- "23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch\n",
- " 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch\n",
- " 23 18 . 0 [_spn_E] [_spn_T] branch\n",
- " 23 18 0 . [_spn_E] [_spn_T] branch\n",
- " 23 18 0 [_spn_E] . [_spn_T] branch\n",
- " 23 18 0 [_spn_E] [_spn_T] . branch\n",
- " 23 18 . _spn_E\n",
- " 23 18 . [pop !-] [--] [++] ifte\n",
- " 23 18 [pop !-] . [--] [++] ifte\n",
- " 23 18 [pop !-] [--] . [++] ifte\n",
- " 23 18 [pop !-] [--] [++] . ifte\n",
- " 23 18 [pop !-] [--] [++] . [nullary not] dipd branch\n",
- " 23 18 [pop !-] [--] [++] [nullary not] . dipd branch\n",
- " 23 18 [pop !-] . nullary not [--] [++] branch\n",
- " 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch\n",
- " 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch\n",
- " 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch\n",
- " 23 18 . stack [pop !-] infra first not [--] [++] branch\n",
- " 23 18 [18 23] . [pop !-] infra first not [--] [++] branch\n",
- " 23 18 [18 23] [pop !-] . infra first not [--] [++] branch\n",
- " 23 18 . pop !- [18 23] swaack first not [--] [++] branch\n",
- " 23 . !- [18 23] swaack first not [--] [++] branch\n",
- " 23 . 0 >= [18 23] swaack first not [--] [++] branch\n",
- " 23 0 . >= [18 23] swaack first not [--] [++] branch\n",
- " True . [18 23] swaack first not [--] [++] branch\n",
- " True [18 23] . swaack first not [--] [++] branch\n",
- " 23 18 [True] . first not [--] [++] branch\n",
- " 23 18 True . not [--] [++] branch\n",
- " 23 18 False . [--] [++] branch\n",
- " 23 18 False [--] . [++] branch\n",
- " 23 18 False [--] [++] . branch\n",
- " 23 18 . --\n",
- " 23 17 . \n"
- ]
- }
- ],
- "source": [
- "V('23 18 spiral_next')"
- ]
}
],
"metadata": {
"kernelspec": {
- "display_name": "Python 2",
- "language": "python",
- "name": "python2"
+ "display_name": "Joypy",
+ "language": "",
+ "name": "thun"
},
"language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.3"
+ "file_extension": ".joy",
+ "mimetype": "text/plain",
+ "name": "Joy"
}
},
"nbformat": 4,
diff --git a/docs/Square_Spiral.md b/docs/Square_Spiral.md
index a217605..27baee4 100644
--- a/docs/Square_Spiral.md
+++ b/docs/Square_Spiral.md
@@ -1,7 +1,3 @@
-```python
-from notebook_preamble import J, V, define
-```
-
# Square Spiral Example Joy Code
@@ -65,28 +61,177 @@ with `<=`:
[abs] ii <=
+
+```Joy
+[_p [abs] ii <=] inscribe
+```
+
+
+
+
+```Joy
+clear 23 -18
+```
+
+ 23 -18
+
+
+```Joy
+[_p] trace
+```
+
+ 23 -18 • _p
+ 23 -18 • [abs] ii <=
+ 23 -18 [abs] • ii <=
+ 23 • abs -18 abs <=
+ 23 • -18 abs <=
+ 23 -18 • abs <=
+ 23 18 • <=
+ false •
+
+ false
+
+
+```Joy
+clear
+```
+
+
+
+### Short-Circuiting Boolean Combinators
+
I've defined two short-circuiting Boolean combinators `&&` and `||` that
each accept two quoted predicate programs, run the first, and
conditionally run the second only if required (to compute the final
Boolean value). They run their predicate arguments `nullary`.
-```python
-define('&& [nullary] cons [nullary [0]] dip branch')
-define('|| [nullary] cons [nullary] dip [1] branch')
+```Joy
+[&& [nullary] cons [nullary [false]] dip branch] inscribe
+[|| [nullary] cons [nullary] dip [true] branch] inscribe
```
+
+
+
+```Joy
+clear
+[true] [false] &&
+```
+
+ false
+
+
+```Joy
+clear
+[false] [true] &&
+```
+
+ false
+
+
+```Joy
+clear
+[true] [false] ||
+```
+
+ true
+
+
+```Joy
+clear
+[false] [true] ||
+```
+
+ true
+
+
+```Joy
+clear
+```
+
+
+
+### Translating the Conditionals
+
Given those, we can define `x != y || x >= 0` as:
- [<>] [pop 0 >=] ||
+ _a == [!=] [pop 0 >=] ||
+
+
+```Joy
+[_a [!=] [pop 0 >=] ||] inscribe
+```
+
+
And `(abs(x) <= abs(y) && (x != y || x >= 0))` as:
- [[abs] ii <=] [[<>] [pop 0 >=] ||] &&
+ _b == [_p] [_a] &&
+
+
+```Joy
+[_b [_p] [_a] &&] inscribe
+```
+
+
It's a little rough, but, as I say, with a little familiarity it becomes
legible.
+
+```Joy
+clear 23 -18
+```
+
+ 23 -18
+
+
+```Joy
+[_b] trace
+```
+
+ 23 -18 • _b
+ 23 -18 • [_p] [_a] &&
+ 23 -18 [_p] • [_a] &&
+ 23 -18 [_p] [_a] • &&
+ 23 -18 [_p] [_a] • [nullary] cons [nullary [false]] dip branch
+ 23 -18 [_p] [_a] [nullary] • cons [nullary [false]] dip branch
+ 23 -18 [_p] [[_a] nullary] • [nullary [false]] dip branch
+ 23 -18 [_p] [[_a] nullary] [nullary [false]] • dip branch
+ 23 -18 [_p] • nullary [false] [[_a] nullary] branch
+ 23 -18 [_p] • [stack] dinfrirst [false] [[_a] nullary] branch
+ 23 -18 [_p] [stack] • dinfrirst [false] [[_a] nullary] branch
+ 23 -18 [_p] [stack] • dip infrst [false] [[_a] nullary] branch
+ 23 -18 • stack [_p] infrst [false] [[_a] nullary] branch
+ 23 -18 [-18 23] • [_p] infrst [false] [[_a] nullary] branch
+ 23 -18 [-18 23] [_p] • infrst [false] [[_a] nullary] branch
+ 23 -18 [-18 23] [_p] • infra first [false] [[_a] nullary] branch
+ 23 -18 • _p [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 -18 • [abs] ii <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 -18 [abs] • ii <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 • abs -18 abs <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 • -18 abs <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 -18 • abs <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 18 • <= [-18 23] swaack first [false] [[_a] nullary] branch
+ false • [-18 23] swaack first [false] [[_a] nullary] branch
+ false [-18 23] • swaack first [false] [[_a] nullary] branch
+ 23 -18 [false] • first [false] [[_a] nullary] branch
+ 23 -18 false • [false] [[_a] nullary] branch
+ 23 -18 false [false] • [[_a] nullary] branch
+ 23 -18 false [false] [[_a] nullary] • branch
+ 23 -18 • false
+ 23 -18 false •
+
+ 23 -18 false
+
+
+```Joy
+clear
+```
+
+
+
### The Increment / Decrement Branches
Turning to the branches of the main `if` statement:
@@ -113,13 +258,6 @@ Similar logic applies to the other branch:
[pop 0 >=] [--] [++] ifte
-### "Not Negative"
-
-
-```python
-define('!- 0 >=')
-```
-
## Putting the Pieces Together
We can assemble the three functions we just defined in quotes and give
@@ -131,6 +269,20 @@ the symmetry of the two branches, we have:
[[pop !-] [--] [++] ifte ]
ifte
+
+```Joy
+[spiral_next
+
+[_b]
+[[ !-] [[++]] [[--]] ifte dip]
+[[pop !-] [--] [++] ifte ]
+ifte
+
+] inscribe
+```
+
+
+
As I was writing this up I realized that, since the `&&` combinator
doesn't consume the stack (below its quoted args), I can unquote the
predicate, swap the branches, and use the `branch` combinator instead of
@@ -141,45 +293,120 @@ predicate, swap the branches, and use the `branch` combinator instead of
[[ !-] [[++]] [[--]] ifte dip]
branch
-
-```python
-define('spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte')
-```
-
Let's try it out:
-```python
-J('0 0 spiral_next')
+```Joy
+clear 0 0
+```
+
+ 0 0
+
+
+```Joy
+spiral_next
```
1 0
-
-```python
-J('1 0 spiral_next')
+```Joy
+spiral_next
```
1 -1
-
-```python
-J('1 -1 spiral_next')
+```Joy
+spiral_next
```
0 -1
-
-```python
-J('0 -1 spiral_next')
+```Joy
+spiral_next
```
-1 -1
+```Joy
+spiral_next
+```
+
+ -1 0
+
+
+```Joy
+spiral_next
+```
+
+ -1 1
+
+
+```Joy
+spiral_next
+```
+
+ 0 1
+
+
+```Joy
+spiral_next
+```
+
+ 1 1
+
+
+```Joy
+spiral_next
+```
+
+ 2 1
+
+
+```Joy
+spiral_next
+```
+
+ 2 0
+
+
+```Joy
+spiral_next
+```
+
+ 2 -1
+
+
+```Joy
+spiral_next
+```
+
+ 2 -2
+
+
+```Joy
+spiral_next
+```
+
+ 1 -2
+
+
+```Joy
+spiral_next
+```
+
+ 0 -2
+
+
+```Joy
+spiral_next
+```
+
+ -1 -2
+
## Turning it into a Generator with `x`
It can be used with the x combinator to make a kind of generator for
@@ -188,7 +415,7 @@ spiral square coordinates.
We can use `codireco` to make a generator
- codireco ::= cons dip rest cons
+ codireco == cons dip rest cons
It will look like this:
@@ -196,19 +423,37 @@ It will look like this:
Here's a trace of how it works:
- [0 [dup ++] codireco] . x
- [0 [dup ++] codireco] . 0 [dup ++] codireco
- [0 [dup ++] codireco] 0 . [dup ++] codireco
- [0 [dup ++] codireco] 0 [dup ++] . codireco
- [0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons
- [0 [dup ++] codireco] [0 dup ++] . dip rest cons
- . 0 dup ++ [0 [dup ++] codireco] rest cons
- 0 . dup ++ [0 [dup ++] codireco] rest cons
- 0 0 . ++ [0 [dup ++] codireco] rest cons
- 0 1 . [0 [dup ++] codireco] rest cons
- 0 1 [0 [dup ++] codireco] . rest cons
- 0 1 [[dup ++] codireco] . cons
- 0 [1 [dup ++] codireco] .
+
+```Joy
+clear
+
+[0 [dup ++] codireco] [x] trace
+```
+
+ [0 [dup ++] codireco] • x
+ [0 [dup ++] codireco] • 0 [dup ++] codireco
+ [0 [dup ++] codireco] 0 • [dup ++] codireco
+ [0 [dup ++] codireco] 0 [dup ++] • codireco
+ [0 [dup ++] codireco] 0 [dup ++] • codi reco
+ [0 [dup ++] codireco] 0 [dup ++] • cons dip reco
+ [0 [dup ++] codireco] [0 dup ++] • dip reco
+ • 0 dup ++ [0 [dup ++] codireco] reco
+ 0 • dup ++ [0 [dup ++] codireco] reco
+ 0 0 • ++ [0 [dup ++] codireco] reco
+ 0 1 • [0 [dup ++] codireco] reco
+ 0 1 [0 [dup ++] codireco] • reco
+ 0 1 [0 [dup ++] codireco] • rest cons
+ 0 1 [[dup ++] codireco] • cons
+ 0 [1 [dup ++] codireco] •
+
+ 0 [1 [dup ++] codireco]
+
+
+```Joy
+clear
+```
+
+
But first we have to change the `spiral_next` function to work on a
quoted pair of integers, and leave a copy of the pair on the stack.
@@ -225,13 +470,12 @@ to:
[x' y']
-```python
-J('[0 0] [spiral_next] infra')
+```Joy
+[0 0] [spiral_next] infra
```
[0 1]
-
So our generator is:
[[x y] [dup [spiral_next] infra] codireco]
@@ -247,30 +491,49 @@ out of the value and stepper function:
----------------------------------------------------
[[0 0] [dup [spiral_next] infra] codireco]
+
+```Joy
+clear
+```
+
+
+
Here it is in action:
-```python
-J('[0 0] [dup [spiral_next] infra] make_generator x x x x pop')
+```Joy
+[0 0] [dup [spiral_next] infra] make_generator x x x x pop
```
[0 0] [0 1] [-1 1] [-1 0]
-
Four `x` combinators, four pairs of coordinates.
+Or you can leave out `dup` and let the value stay in the generator until you want it:
+
+
+```Joy
+clear
+
+[0 0] [[spiral_next] infra] make_generator 50 [x] times first
+```
+
+ [2 4]
+
## Conclusion
So that's an example of Joy code. It's a straightforward translation of
the original. It's a little long for a single definition, you might
break it up like so:
- _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&
+ _spn_Pa == [abs] ii <=
+ _spn_Pb == [!=] [pop 0 >=] ||
+ _spn_P == [_spn_Pa] [_spn_Pb] &&
+
+ _spn_T == [ !-] [[++]] [[--]] ifte dip
+ _spn_E == [pop !-] [--] [++] ifte
- _spn_T ::= [ !-] [[++]] [[--]] ifte dip
- _spn_E ::= [pop !-] [--] [++] ifte
-
- spiral_next ::= _spn_P [_spn_E] [_spn_T] branch
+ spiral_next == _spn_P [_spn_E] [_spn_T] branch
This way it's easy to see that the function is a branch with two
quasi-symmetrical paths.
@@ -280,84 +543,3 @@ pairs, where the next pair in the series can be generated at any time by
using the `x` combinator on the generator (which is just a quoted
expression containing a copy of the current pair and the "stepper
function" to generate the next pair from that.)
-
-
-```python
-define('_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&')
-define('_spn_T [!-] [[++]] [[--]] ifte dip')
-define('_spn_E [pop !-] [--] [++] ifte')
-define('spiral_next _spn_P [_spn_E] [_spn_T] branch')
-```
-
-
-```python
-V('23 18 spiral_next')
-```
-
- . 23 18 spiral_next
- 23 . 18 spiral_next
- 23 18 . spiral_next
- 23 18 . _spn_P [_spn_E] [_spn_T] branch
- 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch
- 23 18 . 0 [_spn_E] [_spn_T] branch
- 23 18 0 . [_spn_E] [_spn_T] branch
- 23 18 0 [_spn_E] . [_spn_T] branch
- 23 18 0 [_spn_E] [_spn_T] . branch
- 23 18 . _spn_E
- 23 18 . [pop !-] [--] [++] ifte
- 23 18 [pop !-] . [--] [++] ifte
- 23 18 [pop !-] [--] . [++] ifte
- 23 18 [pop !-] [--] [++] . ifte
- 23 18 [pop !-] [--] [++] . [nullary not] dipd branch
- 23 18 [pop !-] [--] [++] [nullary not] . dipd branch
- 23 18 [pop !-] . nullary not [--] [++] branch
- 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch
- 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch
- 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch
- 23 18 . stack [pop !-] infra first not [--] [++] branch
- 23 18 [18 23] . [pop !-] infra first not [--] [++] branch
- 23 18 [18 23] [pop !-] . infra first not [--] [++] branch
- 23 18 . pop !- [18 23] swaack first not [--] [++] branch
- 23 . !- [18 23] swaack first not [--] [++] branch
- 23 . 0 >= [18 23] swaack first not [--] [++] branch
- 23 0 . >= [18 23] swaack first not [--] [++] branch
- True . [18 23] swaack first not [--] [++] branch
- True [18 23] . swaack first not [--] [++] branch
- 23 18 [True] . first not [--] [++] branch
- 23 18 True . not [--] [++] branch
- 23 18 False . [--] [++] branch
- 23 18 False [--] . [++] branch
- 23 18 False [--] [++] . branch
- 23 18 . --
- 23 17 .
-
diff --git a/docs/Square_Spiral.rst b/docs/Square_Spiral.rst
index 7b5e67a..8b12aa1 100644
--- a/docs/Square_Spiral.rst
+++ b/docs/Square_Spiral.rst
@@ -1,7 +1,3 @@
-.. code:: ipython3
-
- from notebook_preamble import J, V, define
-
Square Spiral Example Joy Code
==============================
@@ -9,21 +5,21 @@ Here is the example of Joy code from the ``README`` file:
::
- [[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
+ [[[abs]ii <=][[<>][pop !-]||]&&][[!-][[++]][[--]]ifte dip][[pop !-][--][++]ifte]ifte
It might seem unreadable but with a little familiarity it becomes just
as legible as any other notation. Some layout helps:
::
- [ [[abs] ii <=]
- [
- [<>] [pop !-] ||
- ] &&
- ]
- [[ !-] [[++]] [[--]] ifte dip]
- [[pop !-] [--] [++] ifte ]
- ifte
+ [ [[abs] ii <=]
+ [
+ [<>] [pop !-] ||
+ ] &&
+ ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
This function accepts two integers on the stack and increments or
decrements one of them such that the new pair of numbers is the next
@@ -33,34 +29,34 @@ Ulam Spiral).
Original Form
-------------
-It's adapted from `the original code on
+It’s adapted from `the original code on
StackOverflow
`__:
- If all you're trying to do is generate the first N points in the
- spiral (without the original problem's constraint of masking to an N
- x M region), the code becomes very simple:
+ If all you’re trying to do is generate the first N points in the
+ spiral (without the original problem’s constraint of masking to an N
+ x M region), the code becomes very simple:
::
- void spiral(const int N)
- {
- int x = 0;
- int y = 0;
- for(int i = 0; i < N; ++i)
- {
- cout << x << '\t' << y << '\n';
- if(abs(x) <= abs(y) && (x != y || x >= 0))
- x += ((y >= 0) ? 1 : -1);
- else
- y += ((x >= 0) ? -1 : 1);
- }
- }
+ void spiral(const int N)
+ {
+ int x = 0;
+ int y = 0;
+ for(int i = 0; i < N; ++i)
+ {
+ cout << x << '\t' << y << '\n';
+ if(abs(x) <= abs(y) && (x != y || x >= 0))
+ x += ((y >= 0) ? 1 : -1);
+ else
+ y += ((x >= 0) ? -1 : 1);
+ }
+ }
Translation to Joy
------------------
-I'm going to make a function that take two ints (``x`` and ``y``) and
-generates the next pair, we'll turn it into a generator later using the
+I’m going to make a function that take two ints (``x`` and ``y``) and
+generates the next pair, we’ll turn it into a generator later using the
``x`` combinator.
First Boolean Predicate
@@ -71,33 +67,215 @@ to apply ``abs`` to both values and then compare them with ``<=``:
::
- [abs] ii <=
+ [abs] ii <=
-I've defined two short-circuiting Boolean combinators ``&&`` and ``||``
+.. code:: Joy
+
+ [_p [abs] ii <=] inscribe
+
+
+.. parsed-literal::
+
+
+
+.. code:: Joy
+
+ clear 23 -18
+
+
+.. parsed-literal::
+
+ 23 -18
+
+.. code:: Joy
+
+ [_p] trace
+
+
+.. parsed-literal::
+
+ 23 -18 • _p
+ 23 -18 • [abs] ii <=
+ 23 -18 [abs] • ii <=
+ 23 • abs -18 abs <=
+ 23 • -18 abs <=
+ 23 -18 • abs <=
+ 23 18 • <=
+ false •
+
+ false
+
+.. code:: Joy
+
+ clear
+
+
+.. parsed-literal::
+
+
+
+Short-Circuiting Boolean Combinators
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+I’ve defined two short-circuiting Boolean combinators ``&&`` and ``||``
that each accept two quoted predicate programs, run the first, and
conditionally run the second only if required (to compute the final
Boolean value). They run their predicate arguments ``nullary``.
-.. code:: ipython3
+.. code:: Joy
- define('&& [nullary] cons [nullary [0]] dip branch')
- define('|| [nullary] cons [nullary] dip [1] branch')
+ [&& [nullary] cons [nullary [false]] dip branch] inscribe
+ [|| [nullary] cons [nullary] dip [true] branch] inscribe
+
+
+.. parsed-literal::
+
+
+
+.. code:: Joy
+
+ clear
+ [true] [false] &&
+
+
+.. parsed-literal::
+
+ false
+
+.. code:: Joy
+
+ clear
+ [false] [true] &&
+
+
+.. parsed-literal::
+
+ false
+
+.. code:: Joy
+
+ clear
+ [true] [false] ||
+
+
+.. parsed-literal::
+
+ true
+
+.. code:: Joy
+
+ clear
+ [false] [true] ||
+
+
+.. parsed-literal::
+
+ true
+
+.. code:: Joy
+
+ clear
+
+
+.. parsed-literal::
+
+
+
+Translating the Conditionals
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Given those, we can define ``x != y || x >= 0`` as:
::
- [<>] [pop 0 >=] ||
+ _a == [!=] [pop 0 >=] ||
+
+.. code:: Joy
+
+ [_a [!=] [pop 0 >=] ||] inscribe
+
+
+.. parsed-literal::
+
+
And ``(abs(x) <= abs(y) && (x != y || x >= 0))`` as:
::
- [[abs] ii <=] [[<>] [pop 0 >=] ||] &&
+ _b == [_p] [_a] &&
-It's a little rough, but, as I say, with a little familiarity it becomes
+.. code:: Joy
+
+ [_b [_p] [_a] &&] inscribe
+
+
+.. parsed-literal::
+
+
+
+It’s a little rough, but, as I say, with a little familiarity it becomes
legible.
+.. code:: Joy
+
+ clear 23 -18
+
+
+.. parsed-literal::
+
+ 23 -18
+
+.. code:: Joy
+
+ [_b] trace
+
+
+.. parsed-literal::
+
+ 23 -18 • _b
+ 23 -18 • [_p] [_a] &&
+ 23 -18 [_p] • [_a] &&
+ 23 -18 [_p] [_a] • &&
+ 23 -18 [_p] [_a] • [nullary] cons [nullary [false]] dip branch
+ 23 -18 [_p] [_a] [nullary] • cons [nullary [false]] dip branch
+ 23 -18 [_p] [[_a] nullary] • [nullary [false]] dip branch
+ 23 -18 [_p] [[_a] nullary] [nullary [false]] • dip branch
+ 23 -18 [_p] • nullary [false] [[_a] nullary] branch
+ 23 -18 [_p] • [stack] dinfrirst [false] [[_a] nullary] branch
+ 23 -18 [_p] [stack] • dinfrirst [false] [[_a] nullary] branch
+ 23 -18 [_p] [stack] • dip infrst [false] [[_a] nullary] branch
+ 23 -18 • stack [_p] infrst [false] [[_a] nullary] branch
+ 23 -18 [-18 23] • [_p] infrst [false] [[_a] nullary] branch
+ 23 -18 [-18 23] [_p] • infrst [false] [[_a] nullary] branch
+ 23 -18 [-18 23] [_p] • infra first [false] [[_a] nullary] branch
+ 23 -18 • _p [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 -18 • [abs] ii <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 -18 [abs] • ii <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 • abs -18 abs <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 • -18 abs <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 -18 • abs <= [-18 23] swaack first [false] [[_a] nullary] branch
+ 23 18 • <= [-18 23] swaack first [false] [[_a] nullary] branch
+ false • [-18 23] swaack first [false] [[_a] nullary] branch
+ false [-18 23] • swaack first [false] [[_a] nullary] branch
+ 23 -18 [false] • first [false] [[_a] nullary] branch
+ 23 -18 false • [false] [[_a] nullary] branch
+ 23 -18 false [false] • [[_a] nullary] branch
+ 23 -18 false [false] [[_a] nullary] • branch
+ 23 -18 • false
+ 23 -18 false •
+
+ 23 -18 false
+
+.. code:: Joy
+
+ clear
+
+
+.. parsed-literal::
+
+
+
The Increment / Decrement Branches
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -105,42 +283,35 @@ Turning to the branches of the main ``if`` statement:
::
- x += ((y >= 0) ? 1 : -1);
+ x += ((y >= 0) ? 1 : -1);
Rewrite as a hybrid (pseudo-code) ``ifte`` expression:
::
- [y >= 0] [x += 1] [X -= 1] ifte
+ [y >= 0] [x += 1] [X -= 1] ifte
Change each C phrase to Joy code:
::
- [0 >=] [[++] dip] [[--] dip] ifte
+ [0 >=] [[++] dip] [[--] dip] ifte
Factor out the dip from each branch:
::
- [0 >=] [[++]] [[--]] ifte dip
+ [0 >=] [[++]] [[--]] ifte dip
Similar logic applies to the other branch:
::
- y += ((x >= 0) ? -1 : 1);
+ y += ((x >= 0) ? -1 : 1);
- [x >= 0] [y -= 1] [y += 1] ifte
+ [x >= 0] [y -= 1] [y += 1] ifte
- [pop 0 >=] [--] [++] ifte
-
-"Not Negative"
-~~~~~~~~~~~~~~
-
-.. code:: ipython3
-
- define('!- 0 >=')
+ [pop 0 >=] [--] [++] ifte
Putting the Pieces Together
---------------------------
@@ -151,68 +322,184 @@ the symmetry of the two branches, we have:
::
- [[[abs] ii <=] [[<>] [pop !-] ||] &&]
+ [[[abs] ii <=] [[<>] [pop !-] ||] &&]
+ [[ !-] [[++]] [[--]] ifte dip]
+ [[pop !-] [--] [++] ifte ]
+ ifte
+
+.. code:: Joy
+
+ [spiral_next
+
+ [_b]
[[ !-] [[++]] [[--]] ifte dip]
[[pop !-] [--] [++] ifte ]
ifte
+
+ ] inscribe
+
+
+.. parsed-literal::
+
+
As I was writing this up I realized that, since the ``&&`` combinator
-doesn't consume the stack (below its quoted args), I can unquote the
+doesn’t consume the stack (below its quoted args), I can unquote the
predicate, swap the branches, and use the ``branch`` combinator instead
of ``ifte``:
::
- [[abs] ii <=] [[<>] [pop !-] ||] &&
- [[pop !-] [--] [++] ifte ]
- [[ !-] [[++]] [[--]] ifte dip]
- branch
+ [[abs] ii <=] [[<>] [pop !-] ||] &&
+ [[pop !-] [--] [++] ifte ]
+ [[ !-] [[++]] [[--]] ifte dip]
+ branch
-.. code:: ipython3
+Let’s try it out:
- define('spiral_next [[[abs] ii <=] [[<>] [pop !-] ||] &&] [[!-] [[++]] [[--]] ifte dip] [[pop !-] [--] [++] ifte] ifte')
+.. code:: Joy
-Let's try it out:
+ clear 0 0
-.. code:: ipython3
- J('0 0 spiral_next')
+.. parsed-literal::
+
+ 0 0
+
+.. code:: Joy
+
+ spiral_next
.. parsed-literal::
1 0
+.. code:: Joy
-.. code:: ipython3
-
- J('1 0 spiral_next')
+ spiral_next
.. parsed-literal::
1 -1
+.. code:: Joy
-.. code:: ipython3
-
- J('1 -1 spiral_next')
+ spiral_next
.. parsed-literal::
0 -1
+.. code:: Joy
-.. code:: ipython3
-
- J('0 -1 spiral_next')
+ spiral_next
.. parsed-literal::
-1 -1
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ -1 0
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ -1 1
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ 0 1
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ 1 1
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ 2 1
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ 2 0
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ 2 -1
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ 2 -2
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ 1 -2
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ 0 -2
+
+.. code:: Joy
+
+ spiral_next
+
+
+.. parsed-literal::
+
+ -1 -2
Turning it into a Generator with ``x``
--------------------------------------
@@ -224,31 +511,51 @@ We can use ``codireco`` to make a generator
::
- codireco ::= cons dip rest cons
+ codireco == cons dip rest cons
It will look like this:
::
- [value [F] codireco]
+ [value [F] codireco]
-Here's a trace of how it works:
+Here’s a trace of how it works:
-::
+.. code:: Joy
- [0 [dup ++] codireco] . x
- [0 [dup ++] codireco] . 0 [dup ++] codireco
- [0 [dup ++] codireco] 0 . [dup ++] codireco
- [0 [dup ++] codireco] 0 [dup ++] . codireco
- [0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons
- [0 [dup ++] codireco] [0 dup ++] . dip rest cons
- . 0 dup ++ [0 [dup ++] codireco] rest cons
- 0 . dup ++ [0 [dup ++] codireco] rest cons
- 0 0 . ++ [0 [dup ++] codireco] rest cons
- 0 1 . [0 [dup ++] codireco] rest cons
- 0 1 [0 [dup ++] codireco] . rest cons
- 0 1 [[dup ++] codireco] . cons
- 0 [1 [dup ++] codireco] .
+ clear
+
+ [0 [dup ++] codireco] [x] trace
+
+
+.. parsed-literal::
+
+ [0 [dup ++] codireco] • x
+ [0 [dup ++] codireco] • 0 [dup ++] codireco
+ [0 [dup ++] codireco] 0 • [dup ++] codireco
+ [0 [dup ++] codireco] 0 [dup ++] • codireco
+ [0 [dup ++] codireco] 0 [dup ++] • codi reco
+ [0 [dup ++] codireco] 0 [dup ++] • cons dip reco
+ [0 [dup ++] codireco] [0 dup ++] • dip reco
+ • 0 dup ++ [0 [dup ++] codireco] reco
+ 0 • dup ++ [0 [dup ++] codireco] reco
+ 0 0 • ++ [0 [dup ++] codireco] reco
+ 0 1 • [0 [dup ++] codireco] reco
+ 0 1 [0 [dup ++] codireco] • reco
+ 0 1 [0 [dup ++] codireco] • rest cons
+ 0 1 [[dup ++] codireco] • cons
+ 0 [1 [dup ++] codireco] •
+
+ 0 [1 [dup ++] codireco]
+
+.. code:: Joy
+
+ clear
+
+
+.. parsed-literal::
+
+
But first we have to change the ``spiral_next`` function to work on a
quoted pair of integers, and leave a copy of the pair on the stack.
@@ -256,166 +563,107 @@ From:
::
- y x spiral_next
- ---------------------
- y' x'
+ y x spiral_next
+ ---------------------
+ y' x'
to:
::
- [x y] [spiral_next] infra
- -------------------------------
- [x' y']
+ [x y] [spiral_next] infra
+ -------------------------------
+ [x' y']
-.. code:: ipython3
+.. code:: Joy
- J('[0 0] [spiral_next] infra')
+ [0 0] [spiral_next] infra
.. parsed-literal::
[0 1]
-
So our generator is:
::
- [[x y] [dup [spiral_next] infra] codireco]
+ [[x y] [dup [spiral_next] infra] codireco]
Or rather:
::
- [[0 0] [dup [spiral_next] infra] codireco]
+ [[0 0] [dup [spiral_next] infra] codireco]
There is a function ``make_generator`` that will build the generator for
us out of the value and stepper function:
::
- [0 0] [dup [spiral_next] infra] make_generator
- ----------------------------------------------------
- [[0 0] [dup [spiral_next] infra] codireco]
+ [0 0] [dup [spiral_next] infra] make_generator
+ ----------------------------------------------------
+ [[0 0] [dup [spiral_next] infra] codireco]
+
+.. code:: Joy
+
+ clear
+
+
+.. parsed-literal::
+
+
Here it is in action:
-.. code:: ipython3
+.. code:: Joy
- J('[0 0] [dup [spiral_next] infra] make_generator x x x x pop')
+ [0 0] [dup [spiral_next] infra] make_generator x x x x pop
.. parsed-literal::
[0 0] [0 1] [-1 1] [-1 0]
-
Four ``x`` combinators, four pairs of coordinates.
+Or you can leave out ``dup`` and let the value stay in the generator
+until you want it:
+
+.. code:: Joy
+
+ clear
+
+ [0 0] [[spiral_next] infra] make_generator 50 [x] times first
+
+
+.. parsed-literal::
+
+ [2 4]
+
Conclusion
----------
-So that's an example of Joy code. It's a straightforward translation of
-the original. It's a little long for a single definition, you might
+So that’s an example of Joy code. It’s a straightforward translation of
+the original. It’s a little long for a single definition, you might
break it up like so:
::
- _spn_P ::= [[abs] ii <=] [[<>] [pop !-] ||] &&
+ _spn_Pa == [abs] ii <=
+ _spn_Pb == [!=] [pop 0 >=] ||
+ _spn_P == [_spn_Pa] [_spn_Pb] &&
- _spn_T ::= [ !-] [[++]] [[--]] ifte dip
- _spn_E ::= [pop !-] [--] [++] ifte
+ _spn_T == [ !-] [[++]] [[--]] ifte dip
+ _spn_E == [pop !-] [--] [++] ifte
- spiral_next ::= _spn_P [_spn_E] [_spn_T] branch
+ spiral_next == _spn_P [_spn_E] [_spn_T] branch
-This way it's easy to see that the function is a branch with two
+This way it’s easy to see that the function is a branch with two
quasi-symmetrical paths.
We then used this function to make a simple generator of coordinate
pairs, where the next pair in the series can be generated at any time by
using the ``x`` combinator on the generator (which is just a quoted
-expression containing a copy of the current pair and the "stepper
-function" to generate the next pair from that.)
-
-.. code:: ipython3
-
- define('_spn_P [[abs] ii <=] [[<>] [pop !-] ||] &&')
- define('_spn_T [!-] [[++]] [[--]] ifte dip')
- define('_spn_E [pop !-] [--] [++] ifte')
- define('spiral_next _spn_P [_spn_E] [_spn_T] branch')
-
-.. code:: ipython3
-
- V('23 18 spiral_next')
-
-
-.. parsed-literal::
-
- . 23 18 spiral_next
- 23 . 18 spiral_next
- 23 18 . spiral_next
- 23 18 . _spn_P [_spn_E] [_spn_T] branch
- 23 18 . [[abs] ii <=] [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] . [[<>] [pop !-] ||] && [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . && [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[<>] [pop !-] ||] . [nullary] cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[<>] [pop !-] ||] [nullary] . cons [nullary [0]] dip branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] . [nullary [0]] dip branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [[[<>] [pop !-] ||] nullary] [nullary [0]] . dip branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] . nullary [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] . [stack] dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [stack] . dinfrirst [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [[abs] ii <=] [stack] . dip infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . stack [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [18 23] . [[abs] ii <=] infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [18 23] [[abs] ii <=] . infra first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . [abs] ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] . ii <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] . [dip] dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] [dip] . dupdip i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] . dip [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 . abs 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 . 18 [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . [abs] i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [abs] . i <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . abs <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 . <= [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- False . [18 23] swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- False [18 23] . swaack first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 [False] . first [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 False . [0] [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 False [0] . [[[<>] [pop !-] ||] nullary] branch [_spn_E] [_spn_T] branch
- 23 18 False [0] [[[<>] [pop !-] ||] nullary] . branch [_spn_E] [_spn_T] branch
- 23 18 . 0 [_spn_E] [_spn_T] branch
- 23 18 0 . [_spn_E] [_spn_T] branch
- 23 18 0 [_spn_E] . [_spn_T] branch
- 23 18 0 [_spn_E] [_spn_T] . branch
- 23 18 . _spn_E
- 23 18 . [pop !-] [--] [++] ifte
- 23 18 [pop !-] . [--] [++] ifte
- 23 18 [pop !-] [--] . [++] ifte
- 23 18 [pop !-] [--] [++] . ifte
- 23 18 [pop !-] [--] [++] . [nullary not] dipd branch
- 23 18 [pop !-] [--] [++] [nullary not] . dipd branch
- 23 18 [pop !-] . nullary not [--] [++] branch
- 23 18 [pop !-] . [stack] dinfrirst not [--] [++] branch
- 23 18 [pop !-] [stack] . dinfrirst not [--] [++] branch
- 23 18 [pop !-] [stack] . dip infra first not [--] [++] branch
- 23 18 . stack [pop !-] infra first not [--] [++] branch
- 23 18 [18 23] . [pop !-] infra first not [--] [++] branch
- 23 18 [18 23] [pop !-] . infra first not [--] [++] branch
- 23 18 . pop !- [18 23] swaack first not [--] [++] branch
- 23 . !- [18 23] swaack first not [--] [++] branch
- 23 . 0 >= [18 23] swaack first not [--] [++] branch
- 23 0 . >= [18 23] swaack first not [--] [++] branch
- True . [18 23] swaack first not [--] [++] branch
- True [18 23] . swaack first not [--] [++] branch
- 23 18 [True] . first not [--] [++] branch
- 23 18 True . not [--] [++] branch
- 23 18 False . [--] [++] branch
- 23 18 False [--] . [++] branch
- 23 18 False [--] [++] . branch
- 23 18 . --
- 23 17 .
-
+expression containing a copy of the current pair and the “stepper
+function” to generate the next pair from that.)