OSDN Git Service

More update to 4.3.0
[joypy/Thun.git] / docs / 2._Library_Examples.rst
1 Examples (and some documentation) for the Words in the Library
2 ==============================================================
3
4 .. code:: ipython3
5
6     from notebook_preamble import J, V
7
8 Stack Chatter
9 =============
10
11 This is what I like to call the functions that just rearrange things on
12 the stack. (One thing I want to mention is that during a hypothetical
13 compilation phase these "stack chatter" words effectively disappear,
14 because we can map the logical stack locations to registers that remain
15 static for the duration of the computation. This remains to be done but
16 it's "off the shelf" technology.)
17
18 ``clear``
19 ~~~~~~~~~
20
21 .. code:: ipython3
22
23     J('1 2 3 clear')
24
25
26 .. parsed-literal::
27
28     
29
30
31 ``dup`` ``dupd``
32 ~~~~~~~~~~~~~~~~
33
34 .. code:: ipython3
35
36     J('1 2 3 dup')
37
38
39 .. parsed-literal::
40
41     1 2 3 3
42
43
44 .. code:: ipython3
45
46     J('1 2 3 dupd')
47
48
49 .. parsed-literal::
50
51     1 2 2 3
52
53
54 ``enstacken`` ``disenstacken`` ``stack`` ``unstack``
55 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56
57 Replace the stack with a quote of itself.
58
59 .. code:: ipython3
60
61     J('1 2 3 enstacken')
62
63
64 .. parsed-literal::
65
66     [3 2 1]
67
68
69 Unpack a list onto the stack.
70
71 .. code:: ipython3
72
73     J('4 5 6 [3 2 1] unstack')
74
75
76 .. parsed-literal::
77
78     4 5 6 3 2 1
79
80
81 Get the stack on the stack.
82
83 .. code:: ipython3
84
85     J('1 2 3 stack')
86
87
88 .. parsed-literal::
89
90     1 2 3 [3 2 1]
91
92
93 Replace the stack with the list on top. The items appear reversed but
94 they are not, is on the top of both the list and the stack.
95
96 .. code:: ipython3
97
98     J('1 2 3 [4 5 6] disenstacken')
99
100
101 .. parsed-literal::
102
103     6 5 4
104
105
106 ``pop`` ``popd`` ``popop``
107 ~~~~~~~~~~~~~~~~~~~~~~~~~~
108
109 .. code:: ipython3
110
111     J('1 2 3 pop')
112
113
114 .. parsed-literal::
115
116     1 2
117
118
119 .. code:: ipython3
120
121     J('1 2 3 popd')
122
123
124 .. parsed-literal::
125
126     1 3
127
128
129 .. code:: ipython3
130
131     J('1 2 3 popop')
132
133
134 .. parsed-literal::
135
136     1
137
138
139 ``roll<`` ``rolldown`` ``roll>`` ``rollup``
140 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141
142 The "down" and "up" refer to the movement of two of the top three items
143 (displacing the third.)
144
145 .. code:: ipython3
146
147     J('1 2 3 roll<')
148
149
150 .. parsed-literal::
151
152     2 3 1
153
154
155 .. code:: ipython3
156
157     J('1 2 3 roll>')
158
159
160 .. parsed-literal::
161
162     3 1 2
163
164
165 ``swap``
166 ~~~~~~~~
167
168 .. code:: ipython3
169
170     J('1 2 3 swap')
171
172
173 .. parsed-literal::
174
175     1 3 2
176
177
178 ``tuck`` ``over``
179 ~~~~~~~~~~~~~~~~~
180
181 .. code:: ipython3
182
183     J('1 2 3 tuck')
184
185
186 .. parsed-literal::
187
188     1 3 2 3
189
190
191 .. code:: ipython3
192
193     J('1 2 3 over')
194
195
196 .. parsed-literal::
197
198     1 2 3 2
199
200
201 ``unit`` ``quoted`` ``unquoted``
202 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
203
204 .. code:: ipython3
205
206     J('1 2 3 unit')
207
208
209 .. parsed-literal::
210
211     1 2 [3]
212
213
214 .. code:: ipython3
215
216     J('1 2 3 quoted')
217
218
219 .. parsed-literal::
220
221     1 [2] 3
222
223
224 .. code:: ipython3
225
226     J('1 [2] 3 unquoted')
227
228
229 .. parsed-literal::
230
231     1 2 3
232
233
234 .. code:: ipython3
235
236     V('1 [dup] 3 unquoted')  # Unquoting evaluates.  Be aware.
237
238
239 .. parsed-literal::
240
241                   • 1 [dup] 3 unquoted
242                 1 • [dup] 3 unquoted
243           1 [dup] • 3 unquoted
244         1 [dup] 3 • unquoted
245         1 [dup] 3 • [i] dip
246     1 [dup] 3 [i] • dip
247           1 [dup] • i 3
248                 1 • dup 3
249               1 1 • 3
250             1 1 3 • 
251
252
253 List words
254 ==========
255
256 ``concat`` ``swoncat`` ``shunt``
257 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
258
259 .. code:: ipython3
260
261     J('[1 2 3] [4 5 6] concat')
262
263
264 .. parsed-literal::
265
266     [1 2 3 4 5 6]
267
268
269 .. code:: ipython3
270
271     J('[1 2 3] [4 5 6] swoncat')
272
273
274 .. parsed-literal::
275
276     [4 5 6 1 2 3]
277
278
279 .. code:: ipython3
280
281     J('[1 2 3] [4 5 6] shunt')
282
283
284 .. parsed-literal::
285
286     [6 5 4 1 2 3]
287
288
289 ``cons`` ``swons`` ``uncons``
290 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
291
292 .. code:: ipython3
293
294     J('1 [2 3] cons')
295
296
297 .. parsed-literal::
298
299     [1 2 3]
300
301
302 .. code:: ipython3
303
304     J('[2 3] 1 swons')
305
306
307 .. parsed-literal::
308
309     [1 2 3]
310
311
312 .. code:: ipython3
313
314     J('[1 2 3] uncons')
315
316
317 .. parsed-literal::
318
319     1 [2 3]
320
321
322 ``first`` ``second`` ``third`` ``rest``
323 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
324
325 .. code:: ipython3
326
327     J('[1 2 3 4] first')
328
329
330 .. parsed-literal::
331
332     1
333
334
335 .. code:: ipython3
336
337     J('[1 2 3 4] second')
338
339
340 .. parsed-literal::
341
342     2
343
344
345 .. code:: ipython3
346
347     J('[1 2 3 4] third')
348
349
350 .. parsed-literal::
351
352     3
353
354
355 .. code:: ipython3
356
357     J('[1 2 3 4] rest')
358
359
360 .. parsed-literal::
361
362     [2 3 4]
363
364
365 ``flatten``
366 ~~~~~~~~~~~
367
368 .. code:: ipython3
369
370     J('[[1] [2 [3] 4] [5 6]] flatten')
371
372
373 .. parsed-literal::
374
375     [1 2 [3] 4 5 6]
376
377
378 ``getitem`` ``at`` ``of`` ``drop`` ``take``
379 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
380
381 ``at`` and ``getitem`` are the same function. ``of == swap at``
382
383 .. code:: ipython3
384
385     J('[10 11 12 13 14] 2 getitem')
386
387
388 .. parsed-literal::
389
390     12
391
392
393 .. code:: ipython3
394
395     J('[1 2 3 4] 0 at')
396
397
398 .. parsed-literal::
399
400     1
401
402
403 .. code:: ipython3
404
405     J('2 [1 2 3 4] of')
406
407
408 .. parsed-literal::
409
410     3
411
412
413 .. code:: ipython3
414
415     J('[1 2 3 4] 2 drop')
416
417
418 .. parsed-literal::
419
420     [3 4]
421
422
423 .. code:: ipython3
424
425     J('[1 2 3 4] 2 take')  # reverses the order
426
427
428 .. parsed-literal::
429
430     [2 1]
431
432
433 ``reverse`` could be defines as ``reverse == dup size take``
434
435 ``remove``
436 ~~~~~~~~~~
437
438 .. code:: ipython3
439
440     J('[1 2 3 1 4] 1 remove')
441
442
443 .. parsed-literal::
444
445     [2 3 1 4]
446
447
448 ``reverse``
449 ~~~~~~~~~~~
450
451 .. code:: ipython3
452
453     J('[1 2 3 4] reverse')
454
455
456 .. parsed-literal::
457
458     [4 3 2 1]
459
460
461 ``size``
462 ~~~~~~~~
463
464 .. code:: ipython3
465
466     J('[1 1 1 1] size')
467
468
469 .. parsed-literal::
470
471     4
472
473
474 ``swaack``
475 ~~~~~~~~~~
476
477 "Swap stack" swap the list on the top of the stack for the stack, and
478 put the old stack on top of the new one. Think of it as a context
479 switch. Niether of the lists/stacks change their order.
480
481 .. code:: ipython3
482
483     J('1 2 3 [4 5 6] swaack')
484
485
486 .. parsed-literal::
487
488     6 5 4 [3 2 1]
489
490
491 ``choice`` ``select``
492 ~~~~~~~~~~~~~~~~~~~~~
493
494 .. code:: ipython3
495
496     J('23 9 1 choice')
497
498
499 .. parsed-literal::
500
501     9
502
503
504 .. code:: ipython3
505
506     J('23 9 0 choice')
507
508
509 .. parsed-literal::
510
511     23
512
513
514 .. code:: ipython3
515
516     J('[23 9 7] 1 select')  # select is basically getitem, should retire it?
517
518
519 .. parsed-literal::
520
521     9
522
523
524 .. code:: ipython3
525
526     J('[23 9 7] 0 select')
527
528
529 .. parsed-literal::
530
531     23
532
533
534 ``zip``
535 ~~~~~~~
536
537 .. code:: ipython3
538
539     J('[1 2 3] [6 5 4] zip')
540
541
542 .. parsed-literal::
543
544     [[6 1] [5 2] [4 3]]
545
546
547 .. code:: ipython3
548
549     J('[1 2 3] [6 5 4] zip [sum] map')
550
551
552 .. parsed-literal::
553
554     [7 7 7]
555
556
557 Math words
558 ==========
559
560 ``+`` ``add``
561 ~~~~~~~~~~~~~
562
563 .. code:: ipython3
564
565     J('23 9 +')
566
567
568 .. parsed-literal::
569
570     32
571
572
573 ``-`` ``sub``
574 ~~~~~~~~~~~~~
575
576 .. code:: ipython3
577
578     J('23 9 -')
579
580
581 .. parsed-literal::
582
583     14
584
585
586 ``*`` ``mul``
587 ~~~~~~~~~~~~~
588
589 .. code:: ipython3
590
591     J('23 9 *')
592
593
594 .. parsed-literal::
595
596     207
597
598
599 ``/`` ``div`` ``floordiv`` ``truediv``
600 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
601
602 .. code:: ipython3
603
604     J('23 9 /')
605
606
607 .. parsed-literal::
608
609     2.5555555555555554
610
611
612 .. code:: ipython3
613
614     J('23 -9 truediv')
615
616
617 .. parsed-literal::
618
619     -2.5555555555555554
620
621
622 .. code:: ipython3
623
624     J('23 9 div')
625
626
627 .. parsed-literal::
628
629     2.5555555555555554
630
631
632 .. code:: ipython3
633
634     J('23 9 floordiv')
635
636
637 .. parsed-literal::
638
639     2
640
641
642 .. code:: ipython3
643
644     J('23 -9 div')
645
646
647 .. parsed-literal::
648
649     -2.5555555555555554
650
651
652 .. code:: ipython3
653
654     J('23 -9 floordiv')
655
656
657 .. parsed-literal::
658
659     -3
660
661
662 ``%`` ``mod`` ``modulus`` ``rem`` ``remainder``
663 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
664
665 .. code:: ipython3
666
667     J('23 9 %')
668
669
670 .. parsed-literal::
671
672     5
673
674
675 ``neg``
676 ~~~~~~~
677
678 .. code:: ipython3
679
680     J('23 neg -5 neg')
681
682
683 .. parsed-literal::
684
685     -23 5
686
687
688 pow
689 ~~~
690
691 .. code:: ipython3
692
693     J('2 10 pow')
694
695
696 .. parsed-literal::
697
698     1024
699
700
701 ``sqr`` ``sqrt``
702 ~~~~~~~~~~~~~~~~
703
704 .. code:: ipython3
705
706     J('23 sqr')
707
708
709 .. parsed-literal::
710
711     529
712
713
714 .. code:: ipython3
715
716     J('23 sqrt')
717
718
719 .. parsed-literal::
720
721     4.795831523312719
722
723
724 ``++`` ``succ`` ``--`` ``pred``
725 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
726
727 .. code:: ipython3
728
729     J('1 ++')
730
731
732 .. parsed-literal::
733
734     2
735
736
737 .. code:: ipython3
738
739     J('1 --')
740
741
742 .. parsed-literal::
743
744     0
745
746
747 ``<<`` ``lshift`` ``>>`` ``rshift``
748 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
749
750 .. code:: ipython3
751
752     J('8 1 <<')
753
754
755 .. parsed-literal::
756
757     16
758
759
760 .. code:: ipython3
761
762     J('8 1 >>')
763
764
765 .. parsed-literal::
766
767     4
768
769
770 ``average``
771 ~~~~~~~~~~~
772
773 .. code:: ipython3
774
775     J('[1 2 3 5] average')
776
777
778 .. parsed-literal::
779
780     2.75
781
782
783 ``range`` ``range_to_zero`` ``down_to_zero``
784 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
785
786 .. code:: ipython3
787
788     J('5 range')
789
790
791 .. parsed-literal::
792
793     [4 3 2 1 0]
794
795
796 .. code:: ipython3
797
798     J('5 range_to_zero')
799
800
801 .. parsed-literal::
802
803     [0 1 2 3 4 5]
804
805
806 .. code:: ipython3
807
808     J('5 down_to_zero')
809
810
811 .. parsed-literal::
812
813     5 4 3 2 1 0
814
815
816 ``product``
817 ~~~~~~~~~~~
818
819 .. code:: ipython3
820
821     J('[1 2 3 5] product')
822
823
824 .. parsed-literal::
825
826     30
827
828
829 ``sum``
830 ~~~~~~~
831
832 .. code:: ipython3
833
834     J('[1 2 3 5] sum')
835
836
837 .. parsed-literal::
838
839     11
840
841
842 ``min``
843 ~~~~~~~
844
845 .. code:: ipython3
846
847     J('[1 2 3 5] min')
848
849
850 .. parsed-literal::
851
852     1
853
854
855 ``gcd``
856 ~~~~~~~
857
858 .. code:: ipython3
859
860     J('45 30 gcd')
861
862
863 .. parsed-literal::
864
865     15
866
867
868 ``least_fraction``
869 ~~~~~~~~~~~~~~~~~~
870
871 If we represent fractions as a quoted pair of integers [q d] this word
872 reduces them to their ... least common factors or whatever.
873
874 .. code:: ipython3
875
876     J('[45 30] least_fraction')
877
878
879 .. parsed-literal::
880
881     [3.0 2.0]
882
883
884 .. code:: ipython3
885
886     J('[23 12] least_fraction')
887
888
889 .. parsed-literal::
890
891     [23.0 12.0]
892
893
894 Logic and Comparison
895 ====================
896
897 ``?`` ``truthy``
898 ~~~~~~~~~~~~~~~~
899
900 Get the Boolean value of the item on the top of the stack.
901
902 .. code:: ipython3
903
904     J('23 truthy')
905
906
907 .. parsed-literal::
908
909     True
910
911
912 .. code:: ipython3
913
914     J('[] truthy')  # Python semantics.
915
916
917 .. parsed-literal::
918
919     False
920
921
922 .. code:: ipython3
923
924     J('0 truthy')
925
926
927 .. parsed-literal::
928
929     False
930
931
932 ::
933
934     ? == dup truthy
935
936 .. code:: ipython3
937
938     V('23 ?')
939
940
941 .. parsed-literal::
942
943             • 23 ?
944          23 • ?
945          23 • dup truthy
946       23 23 • truthy
947     23 True • 
948
949
950 .. code:: ipython3
951
952     J('[] ?')
953
954
955 .. parsed-literal::
956
957     [] False
958
959
960 .. code:: ipython3
961
962     J('0 ?')
963
964
965 .. parsed-literal::
966
967     0 False
968
969
970 ``&`` ``and``
971 ~~~~~~~~~~~~~
972
973 .. code:: ipython3
974
975     J('23 9 &')
976
977
978 .. parsed-literal::
979
980     1
981
982
983 ``!=`` ``<>`` ``ne``
984 ~~~~~~~~~~~~~~~~~~~~
985
986 .. code:: ipython3
987
988     J('23 9 !=')
989
990
991 .. parsed-literal::
992
993     True
994
995
996 | The usual suspects: - ``<`` ``lt`` - ``<=`` ``le``
997 | - ``=`` ``eq`` - ``>`` ``gt`` - ``>=`` ``ge`` - ``not`` - ``or``
998
999 ``^`` ``xor``
1000 ~~~~~~~~~~~~~
1001
1002 .. code:: ipython3
1003
1004     J('1 1 ^')
1005
1006
1007 .. parsed-literal::
1008
1009     0
1010
1011
1012 .. code:: ipython3
1013
1014     J('1 0 ^')
1015
1016
1017 .. parsed-literal::
1018
1019     1
1020
1021
1022 Miscellaneous
1023 =============
1024
1025 ``help``
1026 ~~~~~~~~
1027
1028 .. code:: ipython3
1029
1030     J('[help] help')
1031
1032
1033 .. parsed-literal::
1034
1035     
1036     ==== Help on help ====
1037     
1038     Accepts a quoted symbol on the top of the stack and prints its docs.
1039     
1040     ---- end (help)
1041     
1042     
1043
1044
1045 ``parse``
1046 ~~~~~~~~~
1047
1048 .. code:: ipython3
1049
1050     J('[parse] help')
1051
1052
1053 .. parsed-literal::
1054
1055     
1056     ==== Help on parse ====
1057     
1058     Parse the string on the stack to a Joy expression.
1059     
1060     ---- end (parse)
1061     
1062     
1063
1064
1065 .. code:: ipython3
1066
1067     J('1 "2 [3] dup" parse')
1068
1069
1070 .. parsed-literal::
1071
1072     1 [2 [3] dup]
1073
1074
1075 ``run``
1076 ~~~~~~~
1077
1078 Evaluate a quoted Joy sequence.
1079
1080 .. code:: ipython3
1081
1082     J('[1 2 dup + +] run')
1083
1084
1085 .. parsed-literal::
1086
1087     [5]
1088
1089
1090 Combinators
1091 ===========
1092
1093 ``app1`` ``app2`` ``app3``
1094 ~~~~~~~~~~~~~~~~~~~~~~~~~~
1095
1096 .. code:: ipython3
1097
1098     J('[app1] help')
1099
1100
1101 .. parsed-literal::
1102
1103     
1104     ==== Help on app1 ====
1105     
1106     Given a quoted program on TOS and anything as the second stack item run
1107     the program and replace the two args with the first result of the
1108     program.
1109     ::
1110     
1111                      ... x [Q] . app1
1112             -----------------------------------
1113                ... [x ...] [Q] . infra first
1114     
1115     ---- end (app1)
1116     
1117     
1118
1119
1120 .. code:: ipython3
1121
1122     J('10 4 [sqr *] app1')
1123
1124
1125 .. parsed-literal::
1126
1127     10 160
1128
1129
1130 .. code:: ipython3
1131
1132     J('10 3 4 [sqr *] app2')
1133
1134
1135 .. parsed-literal::
1136
1137     10 90 160
1138
1139
1140 .. code:: ipython3
1141
1142     J('[app2] help')
1143
1144
1145 .. parsed-literal::
1146
1147     
1148     ==== Help on app2 ====
1149     
1150     Like app1 with two items.
1151     ::
1152     
1153                    ... y x [Q] . app2
1154             -----------------------------------
1155                ... [y ...] [Q] . infra first
1156                    [x ...] [Q]   infra first
1157     
1158     ---- end (app2)
1159     
1160     
1161
1162
1163 .. code:: ipython3
1164
1165     J('10 2 3 4 [sqr *] app3')
1166
1167
1168 .. parsed-literal::
1169
1170     10 40 90 160
1171
1172
1173 ``anamorphism``
1174 ~~~~~~~~~~~~~~~
1175
1176 Given an initial value, a predicate function ``[P]``, and a generator
1177 function ``[G]``, the ``anamorphism`` combinator creates a sequence.
1178
1179 ::
1180
1181        n [P] [G] anamorphism
1182     ---------------------------
1183               [...]
1184
1185 Example, ``range``:
1186
1187 ::
1188
1189     range == [0 <=] [1 - dup] anamorphism
1190
1191 .. code:: ipython3
1192
1193     J('3 [0 <=] [1 - dup] anamorphism')
1194
1195
1196 .. parsed-literal::
1197
1198     [2 1 0]
1199
1200
1201 ``branch``
1202 ~~~~~~~~~~
1203
1204 .. code:: ipython3
1205
1206     J('3 4 1 [+] [*] branch')
1207
1208
1209 .. parsed-literal::
1210
1211     12
1212
1213
1214 .. code:: ipython3
1215
1216     J('3 4 0 [+] [*] branch')
1217
1218
1219 .. parsed-literal::
1220
1221     7
1222
1223
1224 ``cleave``
1225 ~~~~~~~~~~
1226
1227 ::
1228
1229     ... x [P] [Q] cleave
1230
1231 From the original Joy docs: "The cleave combinator expects two
1232 quotations, and below that an item ``x`` It first executes ``[P]``, with
1233 ``x`` on top, and saves the top result element. Then it executes
1234 ``[Q]``, again with ``x``, and saves the top result. Finally it restores
1235 the stack to what it was below ``x`` and pushes the two results P(X) and
1236 Q(X)."
1237
1238 Note that ``P`` and ``Q`` can use items from the stack freely, since the
1239 stack (below ``x``) is restored. ``cleave`` is a kind of *parallel*
1240 primitive, and it would make sense to create a version that uses, e.g.
1241 Python threads or something, to actually run ``P`` and ``Q``
1242 concurrently. The current implementation of ``cleave`` is a definition
1243 in terms of ``app2``:
1244
1245 ::
1246
1247     cleave == [i] app2 [popd] dip
1248
1249 .. code:: ipython3
1250
1251     J('10 2 [+] [-] cleave')
1252
1253
1254 .. parsed-literal::
1255
1256     10 12 8
1257
1258
1259 ``dip`` ``dipd`` ``dipdd``
1260 ~~~~~~~~~~~~~~~~~~~~~~~~~~
1261
1262 .. code:: ipython3
1263
1264     J('1 2 3 4 5 [+] dip')
1265
1266
1267 .. parsed-literal::
1268
1269     1 2 7 5
1270
1271
1272 .. code:: ipython3
1273
1274     J('1 2 3 4 5 [+] dipd')
1275
1276
1277 .. parsed-literal::
1278
1279     1 5 4 5
1280
1281
1282 .. code:: ipython3
1283
1284     J('1 2 3 4 5 [+] dipdd')
1285
1286
1287 .. parsed-literal::
1288
1289     3 3 4 5
1290
1291
1292 ``dupdip``
1293 ~~~~~~~~~~
1294
1295 Expects a quoted program ``[Q]`` on the stack and some item under it,
1296 ``dup`` the item and ``dip`` the quoted program under it.
1297
1298 ::
1299
1300     n [Q] dupdip == n Q n
1301
1302 .. code:: ipython3
1303
1304     V('23 [++] dupdip *')  # N(N + 1)
1305
1306
1307 .. parsed-literal::
1308
1309             • 23 [++] dupdip *
1310          23 • [++] dupdip *
1311     23 [++] • dupdip *
1312          23 • ++ 23 *
1313          24 • 23 *
1314       24 23 • *
1315         552 • 
1316
1317
1318 ``genrec`` ``primrec``
1319 ~~~~~~~~~~~~~~~~~~~~~~
1320
1321 .. code:: ipython3
1322
1323     J('[genrec] help')
1324
1325
1326 .. parsed-literal::
1327
1328     
1329     ==== Help on genrec ====
1330     
1331     General Recursion Combinator.
1332     ::
1333     
1334                               [if] [then] [rec1] [rec2] genrec
1335         ---------------------------------------------------------------------
1336            [if] [then] [rec1 [[if] [then] [rec1] [rec2] genrec] rec2] ifte
1337     
1338     From "Recursion Theory and Joy" (j05cmp.html) by Manfred von Thun:
1339     "The genrec combinator takes four program parameters in addition to
1340     whatever data parameters it needs. Fourth from the top is an if-part,
1341     followed by a then-part. If the if-part yields true, then the then-part
1342     is executed and the combinator terminates. The other two parameters are
1343     the rec1-part and the rec2-part. If the if-part yields false, the
1344     rec1-part is executed. Following that the four program parameters and
1345     the combinator are again pushed onto the stack bundled up in a quoted
1346     form. Then the rec2-part is executed, where it will find the bundled
1347     form. Typically it will then execute the bundled form, either with i or
1348     with app2, or some other combinator."
1349     
1350     The way to design one of these is to fix your base case [then] and the
1351     test [if], and then treat rec1 and rec2 as an else-part "sandwiching"
1352     a quotation of the whole function.
1353     
1354     For example, given a (general recursive) function 'F':
1355     ::
1356     
1357             F == [I] [T] [R1] [R2] genrec
1358     
1359     If the [I] if-part fails you must derive R1 and R2 from:
1360     ::
1361     
1362             ... R1 [F] R2
1363     
1364     Just set the stack arguments in front, and figure out what R1 and R2
1365     have to do to apply the quoted [F] in the proper way.  In effect, the
1366     genrec combinator turns into an ifte combinator with a quoted copy of
1367     the original definition in the else-part:
1368     ::
1369     
1370             F == [I] [T] [R1]   [R2] genrec
1371               == [I] [T] [R1 [F] R2] ifte
1372     
1373     Primitive recursive functions are those where R2 == i.
1374     ::
1375     
1376             P == [I] [T] [R] tailrec
1377               == [I] [T] [R [P] i] ifte
1378               == [I] [T] [R P] ifte
1379     
1380     ---- end (genrec)
1381     
1382     
1383
1384
1385 .. code:: ipython3
1386
1387     J('3 [1 <=] [] [dup --] [i *] genrec')
1388
1389
1390 .. parsed-literal::
1391
1392     6
1393
1394
1395 ``i``
1396 ~~~~~
1397
1398 .. code:: ipython3
1399
1400     V('1 2 3 [+ +] i')
1401
1402
1403 .. parsed-literal::
1404
1405                 • 1 2 3 [+ +] i
1406               1 • 2 3 [+ +] i
1407             1 2 • 3 [+ +] i
1408           1 2 3 • [+ +] i
1409     1 2 3 [+ +] • i
1410           1 2 3 • + +
1411             1 5 • +
1412               6 • 
1413
1414
1415 ``ifte``
1416 ~~~~~~~~
1417
1418 ::
1419
1420     [predicate] [then] [else] ifte
1421
1422 .. code:: ipython3
1423
1424     J('1 2 [1] [+] [*] ifte')
1425
1426
1427 .. parsed-literal::
1428
1429     3
1430
1431
1432 .. code:: ipython3
1433
1434     J('1 2 [0] [+] [*] ifte')
1435
1436
1437 .. parsed-literal::
1438
1439     2
1440
1441
1442 ``infra``
1443 ~~~~~~~~~
1444
1445 .. code:: ipython3
1446
1447     V('1 2 3 [4 5 6] [* +] infra')
1448
1449
1450 .. parsed-literal::
1451
1452                         • 1 2 3 [4 5 6] [* +] infra
1453                       1 • 2 3 [4 5 6] [* +] infra
1454                     1 2 • 3 [4 5 6] [* +] infra
1455                   1 2 3 • [4 5 6] [* +] infra
1456           1 2 3 [4 5 6] • [* +] infra
1457     1 2 3 [4 5 6] [* +] • infra
1458                   6 5 4 • * + [3 2 1] swaack
1459                    6 20 • + [3 2 1] swaack
1460                      26 • [3 2 1] swaack
1461              26 [3 2 1] • swaack
1462              1 2 3 [26] • 
1463
1464
1465 ``loop``
1466 ~~~~~~~~
1467
1468 .. code:: ipython3
1469
1470     J('[loop] help')
1471
1472
1473 .. parsed-literal::
1474
1475     
1476     ==== Help on loop ====
1477     
1478     Basic loop combinator.
1479     ::
1480     
1481                ... True [Q] loop
1482             -----------------------
1483                   ... Q [Q] loop
1484     
1485                ... False [Q] loop
1486             ------------------------
1487                       ...
1488     
1489     ---- end (loop)
1490     
1491     
1492
1493
1494 .. code:: ipython3
1495
1496     V('3 dup [1 - dup] loop')
1497
1498
1499 .. parsed-literal::
1500
1501                   • 3 dup [1 - dup] loop
1502                 3 • dup [1 - dup] loop
1503               3 3 • [1 - dup] loop
1504     3 3 [1 - dup] • loop
1505                 3 • 1 - dup [1 - dup] loop
1506               3 1 • - dup [1 - dup] loop
1507                 2 • dup [1 - dup] loop
1508               2 2 • [1 - dup] loop
1509     2 2 [1 - dup] • loop
1510                 2 • 1 - dup [1 - dup] loop
1511               2 1 • - dup [1 - dup] loop
1512                 1 • dup [1 - dup] loop
1513               1 1 • [1 - dup] loop
1514     1 1 [1 - dup] • loop
1515                 1 • 1 - dup [1 - dup] loop
1516               1 1 • - dup [1 - dup] loop
1517                 0 • dup [1 - dup] loop
1518               0 0 • [1 - dup] loop
1519     0 0 [1 - dup] • loop
1520                 0 • 
1521
1522
1523 ``map`` ``pam``
1524 ~~~~~~~~~~~~~~~
1525
1526 .. code:: ipython3
1527
1528     J('10 [1 2 3] [*] map')
1529
1530
1531 .. parsed-literal::
1532
1533     10 [10 20 30]
1534
1535
1536 .. code:: ipython3
1537
1538     J('10 5 [[*][/][+][-]] pam')
1539
1540
1541 .. parsed-literal::
1542
1543     10 5 [50 2.0 15 5]
1544
1545
1546 ``nullary`` ``unary`` ``binary`` ``ternary``
1547 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1548
1549 Run a quoted program enforcing
1550 `arity <https://en.wikipedia.org/wiki/Arity>`__.
1551
1552 .. code:: ipython3
1553
1554     J('1 2 3 4 5 [+] nullary')
1555
1556
1557 .. parsed-literal::
1558
1559     1 2 3 4 5 9
1560
1561
1562 .. code:: ipython3
1563
1564     J('1 2 3 4 5 [+] unary')
1565
1566
1567 .. parsed-literal::
1568
1569     1 2 3 4 9
1570
1571
1572 .. code:: ipython3
1573
1574     J('1 2 3 4 5 [+] binary')  # + has arity 2 so this is technically pointless...
1575
1576
1577 .. parsed-literal::
1578
1579     1 2 3 9
1580
1581
1582 .. code:: ipython3
1583
1584     J('1 2 3 4 5 [+] ternary')
1585
1586
1587 .. parsed-literal::
1588
1589     1 2 9
1590
1591
1592 ``step``
1593 ~~~~~~~~
1594
1595 .. code:: ipython3
1596
1597     J('[step] help')
1598
1599
1600 .. parsed-literal::
1601
1602     
1603     ==== Help on step ====
1604     
1605     Run a quoted program on each item in a sequence.
1606     ::
1607     
1608                ... [] [Q] . step
1609             -----------------------
1610                       ... .
1611     
1612     
1613                ... [a] [Q] . step
1614             ------------------------
1615                      ... a . Q
1616     
1617     
1618                ... [a b c] [Q] . step
1619             ----------------------------------------
1620                          ... a . Q [b c] [Q] step
1621     
1622     The step combinator executes the quotation on each member of the list
1623     on top of the stack.
1624     
1625     ---- end (step)
1626     
1627     
1628
1629
1630 .. code:: ipython3
1631
1632     V('0 [1 2 3] [+] step')
1633
1634
1635 .. parsed-literal::
1636
1637                   • 0 [1 2 3] [+] step
1638                 0 • [1 2 3] [+] step
1639         0 [1 2 3] • [+] step
1640     0 [1 2 3] [+] • step
1641           0 1 [+] • i [2 3] [+] step
1642               0 1 • + [2 3] [+] step
1643                 1 • [2 3] [+] step
1644           1 [2 3] • [+] step
1645       1 [2 3] [+] • step
1646           1 2 [+] • i [3] [+] step
1647               1 2 • + [3] [+] step
1648                 3 • [3] [+] step
1649             3 [3] • [+] step
1650         3 [3] [+] • step
1651           3 3 [+] • i
1652               3 3 • +
1653                 6 • 
1654
1655
1656 ``times``
1657 ~~~~~~~~~
1658
1659 .. code:: ipython3
1660
1661     V('3 2 1 2 [+] times')
1662
1663
1664 .. parsed-literal::
1665
1666                 • 3 2 1 2 [+] times
1667               3 • 2 1 2 [+] times
1668             3 2 • 1 2 [+] times
1669           3 2 1 • 2 [+] times
1670         3 2 1 2 • [+] times
1671     3 2 1 2 [+] • times
1672           3 2 1 • + 1 [+] times
1673             3 3 • 1 [+] times
1674           3 3 1 • [+] times
1675       3 3 1 [+] • times
1676             3 3 • +
1677               6 • 
1678
1679
1680 ``b``
1681 ~~~~~
1682
1683 .. code:: ipython3
1684
1685     J('[b] help')
1686
1687
1688 .. parsed-literal::
1689
1690     
1691     ==== Help on b ====
1692     
1693     ::
1694     
1695             b == [i] dip i
1696     
1697             ... [P] [Q] b == ... [P] i [Q] i
1698             ... [P] [Q] b == ... P Q
1699     
1700     ---- end (b)
1701     
1702     
1703
1704
1705 .. code:: ipython3
1706
1707     V('1 2 [3] [4] b')
1708
1709
1710 .. parsed-literal::
1711
1712                 • 1 2 [3] [4] b
1713               1 • 2 [3] [4] b
1714             1 2 • [3] [4] b
1715         1 2 [3] • [4] b
1716     1 2 [3] [4] • b
1717             1 2 • 3 4
1718           1 2 3 • 4
1719         1 2 3 4 • 
1720
1721
1722 ``while``
1723 ~~~~~~~~~
1724
1725 ::
1726
1727     [predicate] [body] while
1728
1729 .. code:: ipython3
1730
1731     J('3 [0 >] [dup --] while')
1732
1733
1734 .. parsed-literal::
1735
1736     3 2 1 0
1737
1738
1739 ``x``
1740 ~~~~~
1741
1742 .. code:: ipython3
1743
1744     J('[x] help')
1745
1746
1747 .. parsed-literal::
1748
1749     
1750     ==== Help on x ====
1751     
1752     ::
1753     
1754             x == dup i
1755     
1756             ... [Q] x = ... [Q] dup i
1757             ... [Q] x = ... [Q] [Q] i
1758             ... [Q] x = ... [Q]  Q
1759     
1760     ---- end (x)
1761     
1762     
1763
1764
1765 .. code:: ipython3
1766
1767     V('1 [2] [i 3] x')  # Kind of a pointless example.
1768
1769
1770 .. parsed-literal::
1771
1772                 • 1 [2] [i 3] x
1773               1 • [2] [i 3] x
1774           1 [2] • [i 3] x
1775     1 [2] [i 3] • x
1776     1 [2] [i 3] • i 3
1777           1 [2] • i 3 3
1778               1 • 2 3 3
1779             1 2 • 3 3
1780           1 2 3 • 3
1781         1 2 3 3 • 
1782
1783
1784 ``void``
1785 ========
1786
1787 Implements `**Laws of Form**
1788 *arithmetic* <https://en.wikipedia.org/wiki/Laws_of_Form#The_primary_arithmetic_.28Chapter_4.29>`__
1789 over quote-only datastructures (that is, datastructures that consist
1790 soley of containers, without strings or numbers or anything else.)
1791
1792 .. code:: ipython3
1793
1794     J('[] void')
1795
1796
1797 .. parsed-literal::
1798
1799     False
1800
1801
1802 .. code:: ipython3
1803
1804     J('[[]] void')
1805
1806
1807 .. parsed-literal::
1808
1809     True
1810
1811
1812 .. code:: ipython3
1813
1814     J('[[][[]]] void')
1815
1816
1817 .. parsed-literal::
1818
1819     True
1820
1821
1822 .. code:: ipython3
1823
1824     J('[[[]][[][]]] void')
1825
1826
1827 .. parsed-literal::
1828
1829     False
1830