• R/O
  • HTTP
  • SSH
  • HTTPS

Thun: Commit

Interpreter and library.


Commit MetaInfo

Révision384d391175afce9b3e42fec458d2eba3284c5bf1 (tree)
l'heure2021-12-01 14:00:26
AuteurSimon Forman <sforman@hush...>
CommiterSimon Forman

Message de Log

Switch to Joy kernel.

Change Summary

Modification

--- a/docs/Recursion_Combinators.ipynb
+++ b/docs/Recursion_Combinators.ipynb
@@ -1,21 +1,20 @@
11 {
22 "cells": [
33 {
4- "cell_type": "code",
5- "execution_count": 1,
6- "metadata": {},
7- "outputs": [],
8- "source": [
9- "from notebook_preamble import D, DefinitionWrapper, J, V, define"
10- ]
11- },
12- {
134 "cell_type": "markdown",
145 "metadata": {},
156 "source": [
167 "# Recursion Combinators\n",
178 "\n",
18- "This article describes the `genrec` combinator, how to use it, and several generic specializations.\n",
9+ "This article describes the `genrec` combinator and how to use it, then several generic specializations.\n",
10+ "\n",
11+ "## General Recursive Function\n",
12+ "\n",
13+ "In Joy recursive functions are defined by four quoted programs and the `genrec` combinator.\n",
14+ "\n",
15+ " F == [if] [then] [rec1] [rec2] genrec\n",
16+ "\n",
17+ "This can be thought of as transforming into an \"if..then..else\" expression using the `ifte` combinator and containing a quoted copy of itself in the \"else\" branch:\n",
1918 "\n",
2019 " [if] [then] [rec1] [rec2] genrec\n",
2120 " ---------------------------------------------------------------------\n",
@@ -33,130 +32,123 @@
3332 "the combinator are again pushed onto the stack bundled up in a quoted\n",
3433 "form. Then the rec2-part is executed, where it will find the bundled\n",
3534 "form. Typically it will then execute the bundled form, either with i or\n",
36- "with app2, or some other combinator.\""
37- ]
38- },
39- {
40- "cell_type": "markdown",
41- "metadata": {},
42- "source": [
35+ "with app2, or some other combinator.\"\n",
36+ "\n",
4337 "## Designing Recursive Functions\n",
44- "The way to design one of these is to fix your base case and \n",
45- "test and then treat `R1` and `R2` as an else-part \"sandwiching\"\n",
46- "a quotation of the whole function.\n",
38+ "\n",
39+ "Fix your base case and test functions and then treat `R1` and `R2` as an else-part \"sandwiching\" a quotation of the whole function.\n",
4740 "\n",
4841 "For example, given a (general recursive) function `F`:\n",
4942 "\n",
50- " F == [I] [T] [R1] [R2] genrec\n",
51- " == [I] [T] [R1 [F] R2] ifte\n",
43+ " F == [P] [T] [R1] [R2] genrec\n",
44+ " == [P] [T] [R1 [F] R2] ifte\n",
5245 "\n",
53- "If the `[I]` predicate is false you must derive `R1` and `R2` from:\n",
46+ "Derive `R1` and `R2` from:\n",
5447 "\n",
5548 " ... R1 [F] R2\n",
5649 "\n",
57- "Set the stack arguments in front and figure out what `R1` and `R2`\n",
58- "have to do to apply the quoted `[F]` in the proper way."
59- ]
60- },
61- {
62- "cell_type": "markdown",
63- "metadata": {},
64- "source": [
65- "## Primitive Recursive Functions\n",
66- "Primitive recursive functions are those where `R2 == i`.\n",
50+ "Set the stack arguments in front and figure out what `R1` and `R2` have to do to apply the quoted `[F]` in the proper way.\n",
6751 "\n",
68- " P == [I] [T] [R] primrec\n",
69- " == [I] [T] [R [P] i] ifte\n",
70- " == [I] [T] [R P] ifte"
71- ]
72- },
73- {
74- "cell_type": "markdown",
75- "metadata": {},
76- "source": [
7752 "## [Hylomorphism](https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29)\n",
78- "A [hylomorphism](https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29) is a recursive function `H :: A -> C` that converts a value of type `A` into a value of type `C` by means of:\n",
7953 "\n",
80- "- A generator `G :: A -> (B, A)`\n",
81- "- A combiner `F :: (B, C) -> C`\n",
82- "- A predicate `P :: A -> Bool` to detect the base case\n",
83- "- A base case value `c :: C`\n",
54+ "A [hylomorphism](https://en.wikipedia.org/wiki/Hylomorphism_%28computer_science%29) is a recursive function `H` that converts a value of type `A` into a value of type `C` by means of:\n",
55+ "\n",
56+ "- A generator `G` from `A` to `(B, A)`\n",
57+ "- A combiner `Q` from `(B, C)` to `C`\n",
58+ "- A predicate `P` from `A` to `Bool` to detect the base case\n",
59+ "- A base case value `c` of type `C`, and\n",
8460 "- Recursive calls (zero or more); it has a \"call stack in the form of a cons list\".\n",
8561 "\n",
86- "It may be helpful to see this function implemented in imperative Python code."
87- ]
88- },
89- {
90- "cell_type": "code",
91- "execution_count": 2,
92- "metadata": {},
93- "outputs": [],
94- "source": [
95- "def hylomorphism(c, F, P, G):\n",
96- " '''Return a hylomorphism function H.'''\n",
62+ "It may be helpful to see this function implemented in pseudocode (Python).\n",
9763 "\n",
98- " def H(a):\n",
99- " if P(a):\n",
100- " result = c\n",
101- " else:\n",
64+ " def hylomorphism(c, Q, P, G):\n",
65+ " '''Return a hylomorphism function H.'''\n",
66+ "\n",
67+ " def H(a):\n",
68+ " if P(a):\n",
69+ " return c\n",
10270 " b, aa = G(a)\n",
103- " result = F(b, H(aa)) # b is stored in the stack frame during recursive call to H().\n",
104- " return result\n",
71+ " return Q(b, H(aa))\n",
72+ "\n",
73+ " return H\n",
10574 "\n",
106- " return H"
107- ]
108- },
109- {
110- "cell_type": "markdown",
111- "metadata": {},
112- "source": [
11375 "Cf. [\"Bananas, Lenses, & Barbed Wire\"](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125)\n",
11476 "\n",
115- "Note that during evaluation of `H()` the intermediate `b` values are stored in the Python call stack. This is what is meant by \"call stack in the form of a cons list\"."
116- ]
117- },
118- {
119- "cell_type": "markdown",
120- "metadata": {},
121- "source": [
77+ "Note that during evaluation of `H()` the intermediate `b` values are stored in the Python call stack. This is what is meant by \"call stack in the form of a cons list\".\n",
78+ "\n",
12279 "## Hylomorphism in Joy\n",
80+ "\n",
81+ " a H\n",
82+ " ---------\n",
83+ " c\n",
84+ "\n",
12385 "We can define a combinator `hylomorphism` that will make a hylomorphism combinator `H` from constituent parts.\n",
12486 "\n",
125- " H == [P] c [G] [F] hylomorphism\n",
87+ " H == [P] c [G] [Q] hylomorphism\n",
12688 "\n",
12789 "The function `H` is recursive, so we start with `ifte` and set the else-part to\n",
128- "some function `J` that will contain a quoted copy of `H`. (The then-part just\n",
129- "discards the leftover `a` and replaces it with the base case value `c`.)\n",
90+ "some function `J` that will contain a quoted copy of `H`.\n",
91+ "The then-part just discards the leftover `a` and replaces it with the base case value `c`:\n",
13092 "\n",
13193 " H == [P] [pop c] [J] ifte\n",
13294 "\n",
13395 "The else-part `J` gets just the argument `a` on the stack.\n",
13496 "\n",
13597 " a J\n",
136- " a G The first thing to do is use the generator G\n",
137- " aa b which produces b and a new aa\n",
138- " aa b [H] dip we recur with H on the new aa\n",
139- " aa H b F and run F on the result.\n",
14098 "\n",
141- "This gives us a definition for `J`.\n",
99+ "The first thing to do is use the generator `G` which produces values `b` and a new `aa`:\n",
100+ "\n",
101+ " a G\n",
102+ " ----------\n",
103+ " aa b\n",
104+ "\n",
105+ "So:\n",
106+ "\n",
107+ " J == G J′\n",
108+ "\n",
109+ "Then we recur with `H` on `aa`:\n",
110+ "\n",
111+ " aa b [H] dip\n",
112+ " ------------------\n",
113+ " aa H b\n",
114+ " ------------------\n",
115+ " cc b\n",
116+ "\n",
117+ "So:\n",
118+ "\n",
119+ " J′ == [H] dip J″\n",
120+ "\n",
121+ "And run `Q` on the result:\n",
122+ "\n",
123+ " cc b Q\n",
124+ " ------------\n",
125+ " c\n",
126+ "So:\n",
142127 "\n",
143- " J == G [H] dip F\n",
128+ " J″ == Q\n",
144129 "\n",
145- "Plug it in and convert to genrec.\n",
130+ "Summing up:\n",
146131 "\n",
147- " H == [P] [pop c] [G [H] dip F] ifte\n",
148- " H == [P] [pop c] [G] [dip F] genrec\n",
132+ " J == G J′\n",
133+ " J′ == [H] dip J″\n",
134+ " J″ == Q\n",
135+ "\n",
136+ "This gives us a definition for `J`:\n",
137+ "\n",
138+ " J == G [H] dip Q\n",
139+ "\n",
140+ "Plug it in and convert to genrec:\n",
141+ "\n",
142+ " H == [P] [pop c] [ J ] ifte\n",
143+ " [P] [pop c] [G [H] dip Q] ifte\n",
144+ " [P] [pop c] [G] [dip Q] genrec\n",
149145 "\n",
150146 "This is the form of a hylomorphism in Joy, which nicely illustrates that\n",
151147 "it is a simple specialization of the general recursion combinator.\n",
152148 "\n",
153- " H == [P] c [G] [F] hylomorphism == [P] [pop c] [G] [dip F] genrec"
154- ]
155- },
156- {
157- "cell_type": "markdown",
158- "metadata": {},
159- "source": [
149+ " [P] c [G] [Q] hylomorphism\n",
150+ " [P] [pop c] [G] [dip Q] genrec\n",
151+ "\n",
160152 "## Derivation of `hylomorphism` combinator\n",
161153 "\n",
162154 "Now we just need to derive a definition that builds the `genrec` arguments\n",
@@ -172,8 +164,6 @@
172164 "- Use `unit` to dequote `c`.\n",
173165 "- Use `dipd` to untangle `[unit [pop] swoncat]` from the givens.\n",
174166 "\n",
175- "So:\n",
176- "\n",
177167 " H == [P] [pop c] [G] [dip F] genrec\n",
178168 " [P] [c] [pop] swoncat [G] [F] [dip] swoncat genrec\n",
179169 " [P] c unit [pop] swoncat [G] [F] [dip] swoncat genrec\n",
@@ -187,11 +177,17 @@
187177 },
188178 {
189179 "cell_type": "code",
190- "execution_count": 3,
180+ "execution_count": 1,
191181 "metadata": {},
192- "outputs": [],
182+ "outputs": [
183+ {
184+ "name": "stdout",
185+ "output_type": "stream",
186+ "text": []
187+ }
188+ ],
193189 "source": [
194- "define('hylomorphism == [unit [pop] swoncat] dipd [dip] swoncat genrec')"
190+ "[hylomorphism [unit [pop] swoncat] dipd [dip] swoncat genrec] inscribe"
195191 ]
196192 },
197193 {
@@ -211,11 +207,17 @@
211207 },
212208 {
213209 "cell_type": "code",
214- "execution_count": 4,
210+ "execution_count": 2,
215211 "metadata": {},
216- "outputs": [],
212+ "outputs": [
213+ {
214+ "name": "stdout",
215+ "output_type": "stream",
216+ "text": []
217+ }
218+ ],
217219 "source": [
218- "define('triangular_number == [1 <=] 0 [-- dup] [+] hylomorphism')"
220+ "[triangular_number [1 <=] 0 [-- dup] [+] hylomorphism] inscribe"
219221 ]
220222 },
221223 {
@@ -227,36 +229,45 @@
227229 },
228230 {
229231 "cell_type": "code",
230- "execution_count": 5,
232+ "execution_count": 3,
231233 "metadata": {},
232234 "outputs": [
233235 {
234236 "name": "stdout",
235237 "output_type": "stream",
236238 "text": [
237- "10\n"
239+ "10"
238240 ]
239241 }
240242 ],
241243 "source": [
242- "J('5 triangular_number')"
244+ "5 triangular_number"
243245 ]
244246 },
245247 {
246248 "cell_type": "code",
247- "execution_count": 6,
249+ "execution_count": 4,
248250 "metadata": {},
249251 "outputs": [
250252 {
251253 "name": "stdout",
252254 "output_type": "stream",
253255 "text": [
254- "[0 0 1 3 6 10 15]\n"
256+ "[0 0 1 3 6 10 15 21]"
255257 ]
256258 }
257259 ],
258260 "source": [
259- "J('[0 1 2 3 4 5 6] [triangular_number] map')"
261+ "clear\n",
262+ "\n",
263+ "[0 1 2 3 4 5 6 7] [triangular_number] map"
264+ ]
265+ },
266+ {
267+ "cell_type": "markdown",
268+ "metadata": {},
269+ "source": [
270+ "Neat!"
260271 ]
261272 },
262273 {
@@ -407,6 +418,7 @@
407418 "metadata": {},
408419 "source": [
409420 "### `range` et. al.\n",
421+ "\n",
410422 "An example of an anamorphism is the `range` function which generates the list of integers from 0 to *n* - 1 given *n*.\n",
411423 "\n",
412424 "Each of the above variations can be used to make four slightly different `range` functions."
@@ -423,16 +435,37 @@
423435 },
424436 {
425437 "cell_type": "code",
426- "execution_count": 7,
438+ "execution_count": 5,
427439 "metadata": {},
428- "outputs": [],
440+ "outputs": [
441+ {
442+ "name": "stdout",
443+ "output_type": "stream",
444+ "text": []
445+ }
446+ ],
429447 "source": [
430- "define('range == [0 <=] [] [-- dup] [swons] hylomorphism')"
448+ "clear "
431449 ]
432450 },
433451 {
434452 "cell_type": "code",
435- "execution_count": 8,
453+ "execution_count": 6,
454+ "metadata": {},
455+ "outputs": [
456+ {
457+ "name": "stdout",
458+ "output_type": "stream",
459+ "text": []
460+ }
461+ ],
462+ "source": [
463+ "[range [0 <=] [] [-- dup] [swons] hylomorphism] inscribe"
464+ ]
465+ },
466+ {
467+ "cell_type": "code",
468+ "execution_count": 7,
436469 "metadata": {
437470 "scrolled": false
438471 },
@@ -441,12 +474,12 @@
441474 "name": "stdout",
442475 "output_type": "stream",
443476 "text": [
444- "[4 3 2 1 0]\n"
477+ "[4 3 2 1 0]"
445478 ]
446479 }
447480 ],
448481 "source": [
449- "J('5 range')"
482+ "5 range"
450483 ]
451484 },
452485 {
@@ -454,17 +487,38 @@
454487 "metadata": {},
455488 "source": [
456489 "#### `range` with `H2`\n",
457- " H2 == c swap [P] [pop] [G [F] dip] primrec\n",
458- " == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec"
490+ " H2 == c swap [P] [pop] [G [F] dip] tailrec\n",
491+ " == [] swap [0 <=] [pop] [-- dup [swons] dip] tailrec"
492+ ]
493+ },
494+ {
495+ "cell_type": "code",
496+ "execution_count": 8,
497+ "metadata": {},
498+ "outputs": [
499+ {
500+ "name": "stdout",
501+ "output_type": "stream",
502+ "text": []
503+ }
504+ ],
505+ "source": [
506+ "clear "
459507 ]
460508 },
461509 {
462510 "cell_type": "code",
463511 "execution_count": 9,
464512 "metadata": {},
465- "outputs": [],
513+ "outputs": [
514+ {
515+ "name": "stdout",
516+ "output_type": "stream",
517+ "text": []
518+ }
519+ ],
466520 "source": [
467- "define('range_reverse == [] swap [0 <=] [pop] [-- dup [swons] dip] primrec')"
521+ "[range_reverse [] swap [0 <=] [pop] [-- dup [swons] dip] tailrec] inscribe"
468522 ]
469523 },
470524 {
@@ -478,12 +532,12 @@
478532 "name": "stdout",
479533 "output_type": "stream",
480534 "text": [
481- "[0 1 2 3 4]\n"
535+ "[0 1 2 3 4]"
482536 ]
483537 }
484538 ],
485539 "source": [
486- "J('5 range_reverse')"
540+ "5 range_reverse"
487541 ]
488542 },
489543 {
@@ -499,14 +553,35 @@
499553 "cell_type": "code",
500554 "execution_count": 11,
501555 "metadata": {},
502- "outputs": [],
556+ "outputs": [
557+ {
558+ "name": "stdout",
559+ "output_type": "stream",
560+ "text": []
561+ }
562+ ],
503563 "source": [
504- "define('ranger == [0 <=] [pop []] [[--] dupdip] [dip swons] genrec')"
564+ "clear "
505565 ]
506566 },
507567 {
508568 "cell_type": "code",
509569 "execution_count": 12,
570+ "metadata": {},
571+ "outputs": [
572+ {
573+ "name": "stdout",
574+ "output_type": "stream",
575+ "text": []
576+ }
577+ ],
578+ "source": [
579+ "[ranger [0 <=] [pop []] [[--] dupdip] [dip swons] genrec] inscribe"
580+ ]
581+ },
582+ {
583+ "cell_type": "code",
584+ "execution_count": 13,
510585 "metadata": {
511586 "scrolled": true
512587 },
@@ -515,12 +590,12 @@
515590 "name": "stdout",
516591 "output_type": "stream",
517592 "text": [
518- "[5 4 3 2 1]\n"
593+ "[5 4 3 2 1]"
519594 ]
520595 }
521596 ],
522597 "source": [
523- "J('5 ranger')"
598+ "5 ranger"
524599 ]
525600 },
526601 {
@@ -534,16 +609,37 @@
534609 },
535610 {
536611 "cell_type": "code",
537- "execution_count": 13,
612+ "execution_count": 14,
538613 "metadata": {},
539- "outputs": [],
614+ "outputs": [
615+ {
616+ "name": "stdout",
617+ "output_type": "stream",
618+ "text": []
619+ }
620+ ],
540621 "source": [
541- "define('ranger_reverse == [] swap [0 <=] [pop] [[swons] dupdip --] primrec')"
622+ "clear "
542623 ]
543624 },
544625 {
545626 "cell_type": "code",
546- "execution_count": 14,
627+ "execution_count": 15,
628+ "metadata": {},
629+ "outputs": [
630+ {
631+ "name": "stdout",
632+ "output_type": "stream",
633+ "text": []
634+ }
635+ ],
636+ "source": [
637+ "[ranger_reverse [] swap [0 <=] [pop] [[swons] dupdip --] tailrec] inscribe"
638+ ]
639+ },
640+ {
641+ "cell_type": "code",
642+ "execution_count": 16,
547643 "metadata": {
548644 "scrolled": true
549645 },
@@ -552,19 +648,12 @@
552648 "name": "stdout",
553649 "output_type": "stream",
554650 "text": [
555- "[1 2 3 4 5]\n"
651+ "[1 2 3 4 5]"
556652 ]
557653 }
558654 ],
559655 "source": [
560- "J('5 ranger_reverse')"
561- ]
562- },
563- {
564- "cell_type": "markdown",
565- "metadata": {},
566- "source": [
567- "Hopefully this illustrates the workings of the variations. For more insight you can run the cells using the `V()` function instead of the `J()` function to get a trace of the Joy evaluation."
656+ "5 ranger_reverse"
568657 ]
569658 },
570659 {
@@ -572,54 +661,77 @@
572661 "metadata": {},
573662 "source": [
574663 "## Catamorphism\n",
575- "A catamorphism can be defined as a hylomorphism that uses `[uncons swap]` for `[G]`\n",
576- "and `[[] =]` (or just `[not]`) for the predicate `[P]`. A catamorphic function tears down a list term-by-term and makes some new value.\n",
664+ "A catamorphic function tears down a list term-by-term and makes some new value.\n",
665+ "It can be defined as a hylomorphism that uses `[uncons swap]` for `[G]`\n",
666+ "and `[[] =]` (or just `[not]`) for the predicate `[P]`.\n",
667+ "\n",
668+ " C == [not] c [uncons swap] [F] hylomorphism\n",
577669 "\n",
578- " C == [not] c [uncons swap] [F] hylomorphism"
670+ "An example of a catamorphism is the sum function.\n",
671+ "\n",
672+ " sum == [not] 0 [uncons swap] [+] hylomorphism"
579673 ]
580674 },
581675 {
582676 "cell_type": "code",
583- "execution_count": 15,
677+ "execution_count": 17,
584678 "metadata": {},
585- "outputs": [],
679+ "outputs": [
680+ {
681+ "name": "stdout",
682+ "output_type": "stream",
683+ "text": []
684+ }
685+ ],
586686 "source": [
587- "define('swuncons == uncons swap') # Awkward name."
687+ "clear "
588688 ]
589689 },
590690 {
591- "cell_type": "markdown",
691+ "cell_type": "code",
692+ "execution_count": 18,
592693 "metadata": {},
694+ "outputs": [
695+ {
696+ "name": "stdout",
697+ "output_type": "stream",
698+ "text": []
699+ }
700+ ],
593701 "source": [
594- "An example of a catamorphism is the sum function.\n",
595- "\n",
596- " sum == [not] 0 [swuncons] [+] hylomorphism"
702+ "[sum [not] 0 [uncons swap] [+] hylomorphism] inscribe"
597703 ]
598704 },
599705 {
600706 "cell_type": "code",
601- "execution_count": 16,
707+ "execution_count": 19,
602708 "metadata": {},
603- "outputs": [],
709+ "outputs": [
710+ {
711+ "name": "stdout",
712+ "output_type": "stream",
713+ "text": [
714+ "15"
715+ ]
716+ }
717+ ],
604718 "source": [
605- "define('sum == [not] 0 [swuncons] [+] hylomorphism')"
719+ "[5 4 3 2 1] sum"
606720 ]
607721 },
608722 {
609723 "cell_type": "code",
610- "execution_count": 17,
724+ "execution_count": 20,
611725 "metadata": {},
612726 "outputs": [
613727 {
614728 "name": "stdout",
615729 "output_type": "stream",
616- "text": [
617- "15\n"
618- ]
730+ "text": []
619731 }
620732 ],
621733 "source": [
622- "J('[5 4 3 2 1] sum')"
734+ "clear "
623735 ]
624736 },
625737 {
@@ -632,64 +744,76 @@
632744 },
633745 {
634746 "cell_type": "code",
635- "execution_count": 18,
747+ "execution_count": 21,
636748 "metadata": {},
637749 "outputs": [
638750 {
639751 "name": "stdout",
640752 "output_type": "stream",
641753 "text": [
754+ "\n",
755+ "==== Help on step ====\n",
756+ "\n",
642757 "Run a quoted program on each item in a sequence.\n",
643758 "::\n",
644759 "\n",
645- " ... [] [Q] . step\n",
646- " -----------------------\n",
647- " ... .\n",
760+ " ... [] [Q] . step\n",
761+ " -----------------------\n",
762+ " ... .\n",
648763 "\n",
649764 "\n",
650765 " ... [a] [Q] . step\n",
651766 " ------------------------\n",
652- " ... a . Q\n",
767+ " ... a . Q\n",
653768 "\n",
654769 "\n",
655- " ... [a b c] [Q] . step\n",
656- " ----------------------------------------\n",
657- " ... a . Q [b c] [Q] step\n",
770+ " ... [a b c] [Q] . step\n",
771+ " ----------------------------------------\n",
772+ " ... a . Q [b c] [Q] step\n",
658773 "\n",
659774 "The step combinator executes the quotation on each member of the list\n",
660775 "on top of the stack.\n",
776+ "\n",
777+ "---- end (step)\n",
778+ "\n",
661779 "\n"
662780 ]
663781 }
664782 ],
665783 "source": [
666- "J('[step] help')"
784+ "[step] help"
667785 ]
668786 },
669787 {
670788 "cell_type": "code",
671- "execution_count": 19,
789+ "execution_count": 22,
672790 "metadata": {},
673- "outputs": [],
791+ "outputs": [
792+ {
793+ "name": "stdout",
794+ "output_type": "stream",
795+ "text": []
796+ }
797+ ],
674798 "source": [
675- "define('sum == 0 swap [+] step')"
799+ "[sum 0 swap [+] step] inscribe"
676800 ]
677801 },
678802 {
679803 "cell_type": "code",
680- "execution_count": 20,
804+ "execution_count": 23,
681805 "metadata": {},
682806 "outputs": [
683807 {
684808 "name": "stdout",
685809 "output_type": "stream",
686810 "text": [
687- "15\n"
811+ "15"
688812 ]
689813 }
690814 ],
691815 "source": [
692- "J('[5 4 3 2 1] sum')"
816+ "[5 4 3 2 1] sum"
693817 ]
694818 },
695819 {
@@ -712,16 +836,37 @@
712836 },
713837 {
714838 "cell_type": "code",
715- "execution_count": 21,
839+ "execution_count": 24,
716840 "metadata": {},
717- "outputs": [],
841+ "outputs": [
842+ {
843+ "name": "stdout",
844+ "output_type": "stream",
845+ "text": []
846+ }
847+ ],
718848 "source": [
719- "define('factorial == 1 swap [1 <=] [pop] [[*] dupdip --] primrec')"
849+ "clear"
720850 ]
721851 },
722852 {
723853 "cell_type": "code",
724- "execution_count": 22,
854+ "execution_count": 25,
855+ "metadata": {},
856+ "outputs": [
857+ {
858+ "name": "stdout",
859+ "output_type": "stream",
860+ "text": []
861+ }
862+ ],
863+ "source": [
864+ "[factorial 1 swap [1 <=] [pop] [[*] dupdip --] tailrec] inscribe"
865+ ]
866+ },
867+ {
868+ "cell_type": "code",
869+ "execution_count": 26,
725870 "metadata": {
726871 "scrolled": false
727872 },
@@ -730,12 +875,12 @@
730875 "name": "stdout",
731876 "output_type": "stream",
732877 "text": [
733- "120\n"
878+ "120"
734879 ]
735880 }
736881 ],
737882 "source": [
738- "J('5 factorial')"
883+ "5 factorial"
739884 ]
740885 },
741886 {
@@ -748,54 +893,65 @@
748893 " [1 2 3] tails\n",
749894 " --------------------\n",
750895 " [[] [3] [2 3]]\n",
751- " "
752- ]
753- },
754- {
755- "cell_type": "markdown",
756- "metadata": {},
757- "source": [
758- "We can build as we go, and we want `F` to run after `G`, so we use pattern `H2`:\n",
896+ " \n",
897+ "\n",
898+ "We can build as we go, and we want `Q` to run after `G`, so we use pattern `H2`:\n",
899+ "\n",
900+ " H2 == c swap [P] [pop] [G [Q] dip] tailrec\n",
759901 "\n",
760- " H2 == c swap [P] [pop] [G [F] dip] primrec"
761- ]
762- },
763- {
764- "cell_type": "markdown",
765- "metadata": {},
766- "source": [
767902 "We would use:\n",
768903 "\n",
769904 " c == []\n",
770- " F == swons\n",
905+ " Q == swons\n",
771906 " G == rest dup\n",
772907 " P == not"
773908 ]
774909 },
775910 {
776911 "cell_type": "code",
777- "execution_count": 23,
912+ "execution_count": 27,
913+ "metadata": {},
914+ "outputs": [
915+ {
916+ "name": "stdout",
917+ "output_type": "stream",
918+ "text": []
919+ }
920+ ],
921+ "source": [
922+ "clear"
923+ ]
924+ },
925+ {
926+ "cell_type": "code",
927+ "execution_count": 28,
778928 "metadata": {},
779- "outputs": [],
929+ "outputs": [
930+ {
931+ "name": "stdout",
932+ "output_type": "stream",
933+ "text": []
934+ }
935+ ],
780936 "source": [
781- "define('tails == [] swap [not] [pop] [rest dup [swons] dip] primrec')"
937+ "[tails [] swap [not] [pop] [rest dup [swons] dip] tailrec] inscribe"
782938 ]
783939 },
784940 {
785941 "cell_type": "code",
786- "execution_count": 24,
942+ "execution_count": 29,
787943 "metadata": {},
788944 "outputs": [
789945 {
790946 "name": "stdout",
791947 "output_type": "stream",
792948 "text": [
793- "[[] [3] [2 3]]\n"
949+ "[[] [3] [2 3]]"
794950 ]
795951 }
796952 ],
797953 "source": [
798- "J('[1 2 3] tails')"
954+ "[1 2 3] tails"
799955 ]
800956 },
801957 {
@@ -837,21 +993,14 @@
837993 ],
838994 "metadata": {
839995 "kernelspec": {
840- "display_name": "Python 2",
841- "language": "python",
842- "name": "python2"
996+ "display_name": "Joypy",
997+ "language": "",
998+ "name": "thun"
843999 },
8441000 "language_info": {
845- "codemirror_mode": {
846- "name": "ipython",
847- "version": 2
848- },
849- "file_extension": ".py",
850- "mimetype": "text/x-python",
851- "name": "python",
852- "nbconvert_exporter": "python",
853- "pygments_lexer": "ipython2",
854- "version": "2.7.15"
1001+ "file_extension": ".joy",
1002+ "mimetype": "text/plain",
1003+ "name": "Joy"
8551004 }
8561005 },
8571006 "nbformat": 4,
Afficher sur ancien navigateur de dépôt.