WIP docs update

This commit is contained in:
Simon Forman 2022-01-15 15:22:17 -08:00
parent 0a76eea3e2
commit b05f13fc90
3 changed files with 216 additions and 11 deletions

View File

@ -609,6 +609,212 @@
"However, this creates (and destroys) an intermediate list, which is a waste."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Variations\n",
"\n",
"Let's review the operation of the hylomorphism:\n",
"\n",
" [P] c [G] [Q] H₁ == [P] [pop c] [G] [dip Q] genrec\n",
"\n",
" ... a G [H₁] dip Q\n",
" ... a b [H₁] dip Q\n",
" ... a H₁ b Q\n",
" <predicate omitted>\n",
" ... a G [H₁] dip Q b Q\n",
" ... a″ b [H₁] dip Q b Q\n",
" ... a″ H₁ b Q b Q\n",
" <predicate omitted>\n",
" ... a″ G [H₁] dip Q b Q b Q\n",
" ... a‴ b″ [H₁] dip Q b Q b Q\n",
" ... a‴ H₁ b″ Q b Q b Q\n",
" <predicate omitted>\n",
" ... a‴ pop c b″ Q b Q b Q\n",
" ... c b″ Q b Q b Q\n",
" ... c b Q b Q\n",
" ... c″ b Q\n",
" ... c‴\n",
"\n",
"Notice that `b` values and the `Q` combiner function get pushed into the pending expression (\"continuation\")."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### A tail-recursive version\n",
"\n",
"Now let's try a version that doesn't do that. When you can start with the identity value `c` on the stack and the combiner `Q` can operate as you go using the intermediate results immediately rather than queuing them up, we can do this:\n",
"\n",
" [P] c [G] [Q] H₂ == c [pop P] [popd] [[G] dip Q] tailrec\n",
"\n",
"An important difference is that the combiner function `Q` must accept its arguments in the reverse order and take into account the presence of the `a` value:\n",
"\n",
" ... a c [G] dip Q H₂\n",
" ... a G c Q H₂\n",
" ... a b c Q H₂\n",
" ... a c H₂\n",
" <predicate omitted>\n",
" ... a c [G] dip Q H₂\n",
" ... a G c Q H₂\n",
" ... a″ b c Q H₂\n",
" ... a″ c″ H₂\n",
" <predicate omitted>\n",
" ... a″ c″ [G] dip Q H₂\n",
" ... a″ G c″ Q H₂\n",
" ... a‴ b c″ Q H₂\n",
" ... a‴ c‴ H₂\n",
" <predicate omitted>\n",
" ... a‴ c‴ popd\n",
" ... c‴"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the `c` values are processed by the `Q` combiner function in reverse order as compared to the original version.\n",
"\n",
"#### `range` with `H₂`\n",
"\n",
"For example, if we reimplement the `range` function in the tail-recursive style it generates the list with $0$ at the head rather than $n - 1$:\n",
"\n",
" range_reverse == [] [pop 0 <=] [popd] [[-- dup] dip cons] tailrec\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": []
}
],
"source": [
"clear "
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": []
}
],
"source": [
"[range_reverse [] [pop 0 <=] [popd] [[-- dup] dip cons] tailrec] inscribe"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[4 3 2 1 0] [0 1 2 3 4]"
]
}
],
"source": [
"5 [range] [range_reverse] cleave"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Instead of making `Q` take account of the `c` value we could do this:\n",
"\n",
" ... a b c [Q] ccons dip swap H₂\n",
" ... a [b c Q] dip swap H₂\n",
" ... b c Q a swap H₂\n",
" ... c a swap H₂\n",
" ... a c H₂\n",
"\n",
"This shows that any function `Q` can be converted to `[Q] ccons dip swap` to deal with that `a` value on the stack."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### the old version\n",
"\n",
"Now let's try a version that doesn't do that. When you can start with the identity value `c` on the stack and the combiner `Q` can operate as you go using the intermediate results immediately rather than queuing them up, we can do this:\n",
"\n",
" [P] c [G] [Q] H₂ == c swap [P] [pop] [G [Q] dip] tailrec\n",
"\n",
"An important difference is that the generator function must return its results in the reverse order, and both `Q` and `G` have to take into account the presence of the `c` value:\n",
"\n",
" ... c a G [Q] dip H₂\n",
" ... c b a [Q] dip H₂\n",
" ... c b Q a H₂\n",
" ... c a H₂\n",
" <predicate omitted>\n",
" ... c a G [Q] dip H₂\n",
" ... c b a″ [Q] dip H₂\n",
" ... c b Q a″ H₂\n",
" ... c″ a″ H₂\n",
" <predicate omitted>\n",
" ... c″ a″ G [Q] dip H₂\n",
" ... c″ b″ a‴ [Q] dip H₂\n",
" ... c″ b″ Q a‴ H₂\n",
" ... c‴ a‴ H₂\n",
" <predicate omitted>\n",
" ... c‴ a‴ pop\n",
" ... c‴\n"
]
},
{
"cell_type": "markdown",
"metadata": {},

View File

@ -2654,21 +2654,21 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python2"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,

View File

@ -470,7 +470,6 @@
"source": [
"### Traversal\n",
" [key value] first [left right] [K] map i\n",
" key [value] [left right] [K] map i\n",
" key [left right] [K] map i\n",
" key [lkey rkey ] i\n",
" key lkey rkey"
@ -873,21 +872,21 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python2"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.12"
"pygments_lexer": "ipython3",
"version": "3.7.10"
}
},
"nbformat": 4,