{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Examples (and some documentation) for the Words in the Library" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from notebook_preamble import J, V" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Stack Chatter\n", "This is what I like to call the functions that just rearrange things on the stack. (One thing I want to mention is that during a hypothetical compilation phase these \"stack chatter\" words effectively disappear, because we can map the logical stack locations to registers that remain static for the duration of the computation. This remains to be done but it's \"off the shelf\" technology.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `clear`" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "J('1 2 3 clear')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `dup` `dupd`" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 3\n" ] } ], "source": [ "J('1 2 3 dup')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 2 3\n" ] } ], "source": [ "J('1 2 3 dupd')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `enstacken` `disenstacken` `stack` `unstack`\n", "\n", "Replace the stack with a quote of itself." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3 2 1]\n" ] } ], "source": [ "J('1 2 3 enstacken')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Unpack a list onto the stack." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4 5 6 3 2 1\n" ] } ], "source": [ "J('4 5 6 [3 2 1] unstack')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get the stack on the stack." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 [3 2 1]\n" ] } ], "source": [ "J('1 2 3 stack')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Replace the stack with the list on top.\n", "The items appear reversed but they are not,\n", "is on the top of both the list and the stack." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6 5 4\n" ] } ], "source": [ "J('1 2 3 [4 5 6] disenstacken')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `pop` `popd` `popop`" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2\n" ] } ], "source": [ "J('1 2 3 pop')" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 3\n" ] } ], "source": [ "J('1 2 3 popd')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "J('1 2 3 popop')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `roll<` `rolldown` `roll>` `rollup`\n", "The \"down\" and \"up\" refer to the movement of two of the top three items (displacing the third.)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 3 1\n" ] } ], "source": [ "J('1 2 3 roll<')" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3 1 2\n" ] } ], "source": [ "J('1 2 3 roll>')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `swap`" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 3 2\n" ] } ], "source": [ "J('1 2 3 swap')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `tuck` `over`" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 3 2 3\n" ] } ], "source": [ "J('1 2 3 tuck')" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 2\n" ] } ], "source": [ "J('1 2 3 over')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `unit` `quoted` `unquoted`" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 [3]\n" ] } ], "source": [ "J('1 2 3 unit')" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 [2] 3\n" ] } ], "source": [ "J('1 2 3 quoted')" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3\n" ] } ], "source": [ "J('1 [2] 3 unquoted')" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 1 [dup] 3 unquoted\n", " 1 • [dup] 3 unquoted\n", " 1 [dup] • 3 unquoted\n", " 1 [dup] 3 • unquoted\n", " 1 [dup] 3 • [i] dip\n", "1 [dup] 3 [i] • dip\n", " 1 [dup] • i 3\n", " 1 • dup 3\n", " 1 1 • 3\n", " 1 1 3 • \n" ] } ], "source": [ "V('1 [dup] 3 unquoted') # Unquoting evaluates. Be aware." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# List words" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `concat` `swoncat` `shunt`" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1 2 3 4 5 6]\n" ] } ], "source": [ "J('[1 2 3] [4 5 6] concat')" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[4 5 6 1 2 3]\n" ] } ], "source": [ "J('[1 2 3] [4 5 6] swoncat')" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[6 5 4 1 2 3]\n" ] } ], "source": [ "J('[1 2 3] [4 5 6] shunt')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `cons` `swons` `uncons`" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1 2 3]\n" ] } ], "source": [ "J('1 [2 3] cons')" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1 2 3]\n" ] } ], "source": [ "J('[2 3] 1 swons')" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 [2 3]\n" ] } ], "source": [ "J('[1 2 3] uncons')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `first` `second` `third` `rest`" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "J('[1 2 3 4] first')" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "J('[1 2 3 4] second')" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] } ], "source": [ "J('[1 2 3 4] third')" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2 3 4]\n" ] } ], "source": [ "J('[1 2 3 4] rest')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `flatten`" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1 2 [3] 4 5 6]\n" ] } ], "source": [ "J('[[1] [2 [3] 4] [5 6]] flatten')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `getitem` `at` `of` `drop` `take`\n", "\n", "`at` and `getitem` are the same function. `of == swap at`" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12\n" ] } ], "source": [ "J('[10 11 12 13 14] 2 getitem')" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "J('[1 2 3 4] 0 at')" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] } ], "source": [ "J('2 [1 2 3 4] of')" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3 4]\n" ] } ], "source": [ "J('[1 2 3 4] 2 drop')" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2 1]\n" ] } ], "source": [ "J('[1 2 3 4] 2 take') # reverses the order" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`reverse` could be defines as `reverse == dup size take`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `remove`" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2 3 1 4]\n" ] } ], "source": [ "J('[1 2 3 1 4] 1 remove')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `reverse`" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[4 3 2 1]\n" ] } ], "source": [ "J('[1 2 3 4] reverse')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `size`" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n" ] } ], "source": [ "J('[1 1 1 1] size')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `swaack`\n", "\"Swap stack\" swap the list on the top of the stack for the stack, and put the old stack on top of the new one. Think of it as a context switch. Niether of the lists/stacks change their order." ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6 5 4 [3 2 1]\n" ] } ], "source": [ "J('1 2 3 [4 5 6] swaack')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `choice` `select`" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9\n" ] } ], "source": [ "J('23 9 1 choice')" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "23\n" ] } ], "source": [ "J('23 9 0 choice')" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "9\n" ] } ], "source": [ "J('[23 9 7] 1 select') # select is basically getitem, should retire it?" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "23\n" ] } ], "source": [ "J('[23 9 7] 0 select')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `zip`" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[6 1] [5 2] [4 3]]\n" ] } ], "source": [ "J('[1 2 3] [6 5 4] zip')" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[7 7 7]\n" ] } ], "source": [ "J('[1 2 3] [6 5 4] zip [sum] map')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Math words" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `+` `add`" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "32\n" ] } ], "source": [ "J('23 9 +')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `-` `sub`" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "14\n" ] } ], "source": [ "J('23 9 -')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `*` `mul`" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "207\n" ] } ], "source": [ "J('23 9 *')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `/` `div` `floordiv` `truediv`" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.5555555555555554\n" ] } ], "source": [ "J('23 9 /')" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-2.5555555555555554\n" ] } ], "source": [ "J('23 -9 truediv')" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.5555555555555554\n" ] } ], "source": [ "J('23 9 div')" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "J('23 9 floordiv')" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-2.5555555555555554\n" ] } ], "source": [ "J('23 -9 div')" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-3\n" ] } ], "source": [ "J('23 -9 floordiv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `%` `mod` `modulus` `rem` `remainder`" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n" ] } ], "source": [ "J('23 9 %')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `neg`" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-23 5\n" ] } ], "source": [ "J('23 neg -5 neg')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### pow" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1024\n" ] } ], "source": [ "J('2 10 pow')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `sqr` `sqrt`" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "529\n" ] } ], "source": [ "J('23 sqr')" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4.795831523312719\n" ] } ], "source": [ "J('23 sqrt')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `++` `succ` `--` `pred`" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "J('1 ++')" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n" ] } ], "source": [ "J('1 --')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `<<` `lshift` `>>` `rshift`" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "16\n" ] } ], "source": [ "J('8 1 <<')" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n" ] } ], "source": [ "J('8 1 >>')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `average`" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.75\n" ] } ], "source": [ "J('[1 2 3 5] average')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `range` `range_to_zero` `down_to_zero`" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[4 3 2 1 0]\n" ] } ], "source": [ "J('5 range')" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 1 2 3 4 5]\n" ] } ], "source": [ "J('5 range_to_zero')" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5 4 3 2 1 0\n" ] } ], "source": [ "J('5 down_to_zero')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `product`" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "30\n" ] } ], "source": [ "J('[1 2 3 5] product')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `sum`" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "11\n" ] } ], "source": [ "J('[1 2 3 5] sum')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `min`" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "J('[1 2 3 5] min')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `gcd`" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "15\n" ] } ], "source": [ "J('45 30 gcd')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `least_fraction`\n", "If we represent fractions as a quoted pair of integers [q d] this word reduces them to their ... least common factors or whatever." ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3.0 2.0]\n" ] } ], "source": [ "J('[45 30] least_fraction')" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[23.0 12.0]\n" ] } ], "source": [ "J('[23 12] least_fraction')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Logic and Comparison" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `?` `truthy`\n", "Get the Boolean value of the item on the top of the stack." ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "J('23 truthy')" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "J('[] truthy') # Python semantics." ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "J('0 truthy')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " ? == dup truthy" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 23 ?\n", " 23 • ?\n", " 23 • dup truthy\n", " 23 23 • truthy\n", "23 True • \n" ] } ], "source": [ "V('23 ?')" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[] False\n" ] } ], "source": [ "J('[] ?')" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 False\n" ] } ], "source": [ "J('0 ?')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `&` `and` " ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "J('23 9 &')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `!=` `<>` `ne`" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "J('23 9 !=')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The usual suspects:\n", "- `<` `lt`\n", "- `<=` `le` \n", "- `=` `eq`\n", "- `>` `gt`\n", "- `>=` `ge`\n", "- `not`\n", "- `or`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `^` `xor`" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n" ] } ], "source": [ "J('1 1 ^')" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "J('1 0 ^')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Miscellaneous" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `help`" ] }, { "cell_type": "code", "execution_count": 85, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Help on help ====\n", "\n", "Accepts a quoted symbol on the top of the stack and prints its docs.\n", "\n", "---- end (help)\n", "\n", "\n" ] } ], "source": [ "J('[help] help')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `parse`" ] }, { "cell_type": "code", "execution_count": 86, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Help on parse ====\n", "\n", "Parse the string on the stack to a Joy expression.\n", "\n", "---- end (parse)\n", "\n", "\n" ] } ], "source": [ "J('[parse] help')" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 [2 [3] dup]\n" ] } ], "source": [ "J('1 \"2 [3] dup\" parse')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `run`\n", "Evaluate a quoted Joy sequence." ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5]\n" ] } ], "source": [ "J('[1 2 dup + +] run')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Combinators" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `app1` `app2` `app3`" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Help on app1 ====\n", "\n", "Given a quoted program on TOS and anything as the second stack item run\n", "the program and replace the two args with the first result of the\n", "program.\n", "::\n", "\n", " ... x [Q] . app1\n", " -----------------------------------\n", " ... [x ...] [Q] . infra first\n", "\n", "---- end (app1)\n", "\n", "\n" ] } ], "source": [ "J('[app1] help')" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 160\n" ] } ], "source": [ "J('10 4 [sqr *] app1')" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 90 160\n" ] } ], "source": [ "J('10 3 4 [sqr *] app2')" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Help on app2 ====\n", "\n", "Like app1 with two items.\n", "::\n", "\n", " ... y x [Q] . app2\n", " -----------------------------------\n", " ... [y ...] [Q] . infra first\n", " [x ...] [Q] infra first\n", "\n", "---- end (app2)\n", "\n", "\n" ] } ], "source": [ "J('[app2] help')" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 40 90 160\n" ] } ], "source": [ "J('10 2 3 4 [sqr *] app3')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `anamorphism`\n", "Given an initial value, a predicate function `[P]`, and a generator function `[G]`, the `anamorphism` combinator creates a sequence.\n", "\n", " n [P] [G] anamorphism\n", " ---------------------------\n", " [...]\n", "\n", "Example, `range`:\n", "\n", " range == [0 <=] [1 - dup] anamorphism" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2 1 0]\n" ] } ], "source": [ "J('3 [0 <=] [1 - dup] anamorphism')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `branch`" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12\n" ] } ], "source": [ "J('3 4 1 [+] [*] branch')" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "7\n" ] } ], "source": [ "J('3 4 0 [+] [*] branch')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `cleave`\n", " ... x [P] [Q] cleave\n", "\n", "From the original Joy docs: \"The cleave combinator expects two quotations, and below that an item `x`\n", "It first executes `[P]`, with `x` on top, and saves the top result element.\n", "Then it executes `[Q]`, again with `x`, and saves the top result.\n", "Finally it restores the stack to what it was below `x` and pushes the two\n", "results P(X) and Q(X).\"\n", "\n", "Note that `P` and `Q` can use items from the stack freely, since the stack (below `x`) is restored. `cleave` is a kind of *parallel* primitive, and it would make sense to create a version that uses, e.g. Python threads or something, to actually run `P` and `Q` concurrently. The current implementation of `cleave` is a definition in terms of `app2`:\n", "\n", " cleave == [i] app2 [popd] dip" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 12 8\n" ] } ], "source": [ "J('10 2 [+] [-] cleave')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `dip` `dipd` `dipdd`" ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 7 5\n" ] } ], "source": [ "J('1 2 3 4 5 [+] dip')" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 5 4 5\n" ] } ], "source": [ "J('1 2 3 4 5 [+] dipd')" ] }, { "cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3 3 4 5\n" ] } ], "source": [ "J('1 2 3 4 5 [+] dipdd')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `dupdip`\n", "Expects a quoted program `[Q]` on the stack and some item under it, `dup` the item and `dip` the quoted program under it.\n", "\n", " n [Q] dupdip == n Q n" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 23 [++] dupdip *\n", " 23 • [++] dupdip *\n", "23 [++] • dupdip *\n", " 23 • ++ 23 *\n", " 24 • 23 *\n", " 24 23 • *\n", " 552 • \n" ] } ], "source": [ "V('23 [++] dupdip *') # N(N + 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `genrec` `primrec`" ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Help on genrec ====\n", "\n", "General Recursion Combinator.\n", "::\n", "\n", " [if] [then] [rec1] [rec2] genrec\n", " ---------------------------------------------------------------------\n", " [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte\n", "\n", "From \"Recursion Theory and Joy\" (j05cmp.html) by Manfred von Thun:\n", "\"The genrec combinator takes four program parameters in addition to\n", "whatever data parameters it needs. Fourth from the top is an if-part,\n", "followed by a then-part. If the if-part yields true, then the then-part\n", "is executed and the combinator terminates. The other two parameters are\n", "the rec1-part and the rec2-part. If the if-part yields false, the\n", "rec1-part is executed. Following that the four program parameters and\n", "the combinator are again pushed onto the stack bundled up in a quoted\n", "form. Then the rec2-part is executed, where it will find the bundled\n", "form. Typically it will then execute the bundled form, either with i or\n", "with app2, or some other combinator.\"\n", "\n", "The way to design one of these is to fix your base case [then] and the\n", "test [if], and then treat rec1 and rec2 as an else-part \"sandwiching\"\n", "a quotation of the whole function.\n", "\n", "For example, given a (general recursive) function 'F':\n", "::\n", "\n", " F == [I] [T] [R1] [R2] genrec\n", "\n", "If the [I] if-part fails you must derive R1 and R2 from:\n", "::\n", "\n", " ... R1 [F] R2\n", "\n", "Just set the stack arguments in front, and figure out what R1 and R2\n", "have to do to apply the quoted [F] in the proper way. In effect, the\n", "genrec combinator turns into an ifte combinator with a quoted copy of\n", "the original definition in the else-part:\n", "::\n", "\n", " F == [I] [T] [R1] [R2] genrec\n", " == [I] [T] [R1 [F] R2] ifte\n", "\n", "Primitive recursive functions are those where R2 == i.\n", "::\n", "\n", " P == [I] [T] [R] tailrec\n", " == [I] [T] [R [P] i] ifte\n", " == [I] [T] [R P] ifte\n", "\n", "---- end (genrec)\n", "\n", "\n" ] } ], "source": [ "J('[genrec] help')" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "6\n" ] } ], "source": [ "J('3 [1 <=] [] [dup --] [i *] genrec')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `i`" ] }, { "cell_type": "code", "execution_count": 104, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 1 2 3 [+ +] i\n", " 1 • 2 3 [+ +] i\n", " 1 2 • 3 [+ +] i\n", " 1 2 3 • [+ +] i\n", "1 2 3 [+ +] • i\n", " 1 2 3 • + +\n", " 1 5 • +\n", " 6 • \n" ] } ], "source": [ "V('1 2 3 [+ +] i')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `ifte`\n", " [predicate] [then] [else] ifte" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] } ], "source": [ "J('1 2 [1] [+] [*] ifte')" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "J('1 2 [0] [+] [*] ifte')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `infra`" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 1 2 3 [4 5 6] [* +] infra\n", " 1 • 2 3 [4 5 6] [* +] infra\n", " 1 2 • 3 [4 5 6] [* +] infra\n", " 1 2 3 • [4 5 6] [* +] infra\n", " 1 2 3 [4 5 6] • [* +] infra\n", "1 2 3 [4 5 6] [* +] • infra\n", " 6 5 4 • * + [3 2 1] swaack\n", " 6 20 • + [3 2 1] swaack\n", " 26 • [3 2 1] swaack\n", " 26 [3 2 1] • swaack\n", " 1 2 3 [26] • \n" ] } ], "source": [ "V('1 2 3 [4 5 6] [* +] infra')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `loop`" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Help on loop ====\n", "\n", "Basic loop combinator.\n", "::\n", "\n", " ... True [Q] loop\n", " -----------------------\n", " ... Q [Q] loop\n", "\n", " ... False [Q] loop\n", " ------------------------\n", " ...\n", "\n", "---- end (loop)\n", "\n", "\n" ] } ], "source": [ "J('[loop] help')" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 3 dup [1 - dup] loop\n", " 3 • dup [1 - dup] loop\n", " 3 3 • [1 - dup] loop\n", "3 3 [1 - dup] • loop\n", " 3 • 1 - dup [1 - dup] loop\n", " 3 1 • - dup [1 - dup] loop\n", " 2 • dup [1 - dup] loop\n", " 2 2 • [1 - dup] loop\n", "2 2 [1 - dup] • loop\n", " 2 • 1 - dup [1 - dup] loop\n", " 2 1 • - dup [1 - dup] loop\n", " 1 • dup [1 - dup] loop\n", " 1 1 • [1 - dup] loop\n", "1 1 [1 - dup] • loop\n", " 1 • 1 - dup [1 - dup] loop\n", " 1 1 • - dup [1 - dup] loop\n", " 0 • dup [1 - dup] loop\n", " 0 0 • [1 - dup] loop\n", "0 0 [1 - dup] • loop\n", " 0 • \n" ] } ], "source": [ "V('3 dup [1 - dup] loop')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `map` `pam`" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 [10 20 30]\n" ] } ], "source": [ "J('10 [1 2 3] [*] map')" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10 5 [50 2.0 15 5]\n" ] } ], "source": [ "J('10 5 [[*][/][+][-]] pam')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `nullary` `unary` `binary` `ternary`\n", "Run a quoted program enforcing [arity](https://en.wikipedia.org/wiki/Arity)." ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 4 5 9\n" ] } ], "source": [ "J('1 2 3 4 5 [+] nullary')" ] }, { "cell_type": "code", "execution_count": 113, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 4 9\n" ] } ], "source": [ "J('1 2 3 4 5 [+] unary')" ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 3 9\n" ] } ], "source": [ "J('1 2 3 4 5 [+] binary') # + has arity 2 so this is technically pointless..." ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 2 9\n" ] } ], "source": [ "J('1 2 3 4 5 [+] ternary')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `step`" ] }, { "cell_type": "code", "execution_count": 116, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Help on step ====\n", "\n", "Run a quoted program on each item in a sequence.\n", "::\n", "\n", " ... [] [Q] . step\n", " -----------------------\n", " ... .\n", "\n", "\n", " ... [a] [Q] . step\n", " ------------------------\n", " ... a . Q\n", "\n", "\n", " ... [a b c] [Q] . step\n", " ----------------------------------------\n", " ... a . Q [b c] [Q] step\n", "\n", "The step combinator executes the quotation on each member of the list\n", "on top of the stack.\n", "\n", "---- end (step)\n", "\n", "\n" ] } ], "source": [ "J('[step] help')" ] }, { "cell_type": "code", "execution_count": 117, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 0 [1 2 3] [+] step\n", " 0 • [1 2 3] [+] step\n", " 0 [1 2 3] • [+] step\n", "0 [1 2 3] [+] • step\n", " 0 1 [+] • i [2 3] [+] step\n", " 0 1 • + [2 3] [+] step\n", " 1 • [2 3] [+] step\n", " 1 [2 3] • [+] step\n", " 1 [2 3] [+] • step\n", " 1 2 [+] • i [3] [+] step\n", " 1 2 • + [3] [+] step\n", " 3 • [3] [+] step\n", " 3 [3] • [+] step\n", " 3 [3] [+] • step\n", " 3 3 [+] • i\n", " 3 3 • +\n", " 6 • \n" ] } ], "source": [ "V('0 [1 2 3] [+] step')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `times`" ] }, { "cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 3 2 1 2 [+] times\n", " 3 • 2 1 2 [+] times\n", " 3 2 • 1 2 [+] times\n", " 3 2 1 • 2 [+] times\n", " 3 2 1 2 • [+] times\n", "3 2 1 2 [+] • times\n", " 3 2 1 • + 1 [+] times\n", " 3 3 • 1 [+] times\n", " 3 3 1 • [+] times\n", " 3 3 1 [+] • times\n", " 3 3 • +\n", " 6 • \n" ] } ], "source": [ "V('3 2 1 2 [+] times')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `b`" ] }, { "cell_type": "code", "execution_count": 119, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Help on b ====\n", "\n", "::\n", "\n", " b == [i] dip i\n", "\n", " ... [P] [Q] b == ... [P] i [Q] i\n", " ... [P] [Q] b == ... P Q\n", "\n", "---- end (b)\n", "\n", "\n" ] } ], "source": [ "J('[b] help')" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 1 2 [3] [4] b\n", " 1 • 2 [3] [4] b\n", " 1 2 • [3] [4] b\n", " 1 2 [3] • [4] b\n", "1 2 [3] [4] • b\n", " 1 2 • 3 4\n", " 1 2 3 • 4\n", " 1 2 3 4 • \n" ] } ], "source": [ "V('1 2 [3] [4] b')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `while`\n", " [predicate] [body] while" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3 2 1 0\n" ] } ], "source": [ "J('3 [0 >] [dup --] while')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### `x`" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "==== Help on x ====\n", "\n", "::\n", "\n", " x == dup i\n", "\n", " ... [Q] x = ... [Q] dup i\n", " ... [Q] x = ... [Q] [Q] i\n", " ... [Q] x = ... [Q] Q\n", "\n", "---- end (x)\n", "\n", "\n" ] } ], "source": [ "J('[x] help')" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " • 1 [2] [i 3] x\n", " 1 • [2] [i 3] x\n", " 1 [2] • [i 3] x\n", "1 [2] [i 3] • x\n", "1 [2] [i 3] • i 3\n", " 1 [2] • i 3 3\n", " 1 • 2 3 3\n", " 1 2 • 3 3\n", " 1 2 3 • 3\n", " 1 2 3 3 • \n" ] } ], "source": [ "V('1 [2] [i 3] x') # Kind of a pointless example." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# `void`\n", "Implements [**Laws of Form** *arithmetic*](https://en.wikipedia.org/wiki/Laws_of_Form#The_primary_arithmetic_.28Chapter_4.29) over quote-only datastructures (that is, datastructures that consist soley of containers, without strings or numbers or anything else.)" ] }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "J('[] void')" ] }, { "cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "J('[[]] void')" ] }, { "cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n" ] } ], "source": [ "J('[[][[]]] void')" ] }, { "cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n" ] } ], "source": [ "J('[[[]][[][]]] void')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "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" } }, "nbformat": 4, "nbformat_minor": 2 }